класс DRb::DRbServer
Class представляющий экземпляр сервера drb.
Сервер DRbServer должен быть запущен в локальном процессе перед тем, как будут приняты какие-либо входящие вызовы dRuby или как любые локальные объекты могут быть переданы как ссылки dRuby удалённым процессам, даже если эти локальные объекты никогда фактически не вызываются удалённо. Вам не нужно запускать DRbServer в локальном процессе, если вы только делаете исходящие вызовы dRuby, передавая сериализованные параметры.
Если не используются несколько серверов, локальный DRbServer обычно запускается вызовом DRb.start_service.
Константы
- INSECURE_METHOD
-
Список небезопасных методов.
Эти методы нельзя вызывать через dRuby.
Атрибуты
Настройка этого сервера DRbServer
Объект front сервера DRbServer.
Этот объект получает удалённые вызовы методов, которые делаются на серверном URI отдельном объекте с идентификатором объекта.
Главный поток этого DRbServer.
Это поток, который прослушивает и принимает подключения от клиентов, а не тот, который обрабатывает сеанс запроса-ответа каждого клиента.
URI этого DRbServer.
Публичные методы класса
# File lib/drb/drb.rb, line 1360 def self.default_argc_limit(argc) @@argc_limit = argc end
Set значение по умолчанию для параметра :argc_limit.
См. new(). Изначальное значение по умолчанию равно 256.
# File lib/drb/drb.rb, line 1367 def self.default_load_limit(sz) @@load_limit = sz end
Set значение по умолчанию для параметра :load_limit.
См. new(). Изначальное значение по умолчанию 25 МБ.
# File lib/drb/drb.rb, line 1454
def initialize(uri=nil, front=nil, config_or_acl=nil)
if Hash === config_or_acl
config = config_or_acl.dup
else
acl = config_or_acl || @@acl
config = {
:tcp_acl => acl
}
end
@config = self.class.make_config(config)
@protocol = DRbProtocol.open_server(uri, @config)
@uri = @protocol.uri
@exported_uri = [@uri]
@front = front
@idconv = @config[:idconv]
@grp = ThreadGroup.new
@thread = run
DRb.regist_server(self)
end Создаёт новый экземпляр DRbServer.
uri — URI для привязки. Обычно имеет вид 'druby://<hostname>:<port>', где <hostname> — имя хоста локальной машины. Если nil, то будет привязано к системному имени хоста на порте, выбранном системой; эти значения можно получить из атрибута uri. 'druby:' указывает на протокол транспорта dRuby по умолчанию; вместо него можно указать другой протокол, например, 'drbunix:'.
front — объект front для сервера, то есть объект, которому будут передаваться удалённые вызовы методов на сервере. Если nil, то сервер не будет принимать удалённые вызовы методов.
Если config_or_acl является хэшем, это конфигурация для использования на этом сервере. Признаются следующие параметры:
- :idconv
-
объект преобразования идентификатора в объект. По умолчанию это экземпляр класса
DRb::DRbIdConv. - :verbose
-
если true, все неудачные удалённые вызовы методов объектов на сервере будут записываться в $stdout. По умолчанию false.
- :tcp_acl
-
список контроля доступа для этого сервера. См. класс
ACLиз основного дистрибутива dRuby. - :load_limit
-
максимальный размер сообщения в байтах, принимаемый сервером. По умолчанию 25 МБ (26214400).
- :argc_limit
-
максимальное количество аргументов удалённого метода, принимаемых сервером. По умолчанию 256.
Значения этих параметров по умолчанию можно изменить на уровне класса методами default_argc_limit, default_load_limit, default_acl, default_id_conv и verbose=
Если config_or_acl не является хэшем, но не nil, предполагается, что это список контроля доступа для этого сервера. См. параметр :tcp_acl для получения более подробной информации.
Если ни один другой сервер в настоящее время не установлен в качестве основного сервера, этот сервер станет основным.
Сервер немедленно начнёт работу в собственном потоке.
# File lib/drb/drb.rb, line 1397 def self.verbose @@verbose end
Получить значение параметра :verbose по умолчанию.
# File lib/drb/drb.rb, line 1392 def self.verbose=(on) @@verbose = on end
Set значение параметра :verbose по умолчанию.
См. new(). Изначальное значение по умолчанию false.
Публичные методы экземпляра
# File lib/drb/drb.rb, line 1514 def alive? @thread.alive? end
Является ли этот сервер активным?
# File lib/drb/drb.rb, line 1602
def check_insecure_method(obj, msg_id)
return true if Proc === obj && msg_id == :__drb_yield
raise(ArgumentError, "#{any_to_s(msg_id)} is not a symbol") unless Symbol == msg_id.class
raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id)
case obj
when Object
if obj.private_methods.include?(msg_id)
desc = any_to_s(obj)
raise NoMethodError, "private method `#{msg_id}' called for #{desc}"
elsif obj.protected_methods.include?(msg_id)
desc = any_to_s(obj)
raise NoMethodError, "protected method `#{msg_id}' called for #{desc}"
else
true
end
else
if Kernel.instance_method(:private_methods).bind(obj).call.include?(msg_id)
desc = any_to_s(obj)
raise NoMethodError, "private method `#{msg_id}' called for #{desc}"
elsif Kernel.instance_method(:protected_methods).bind(obj).call.include?(msg_id)
desc = any_to_s(obj)
raise NoMethodError, "protected method `#{msg_id}' called for #{desc}"
else
true
end
end
end Проверяет, можно ли вызвать метод через dRuby.
obj — объект, на котором мы хотим вызвать метод. msg_id — имя метода, как Symbol.
Если метод — небезопасный метод (см. insecure_method?), выбрасывается SecurityError. Если метод является приватным или не определён, выбрасывается NameError.
# File lib/drb/drb.rb, line 1519 def here?(uri) @exported_uri.include?(uri) end
Является ли uri URI для этого сервера?
# File lib/drb/drb.rb, line 1524
def stop_service
DRb.remove_server(self)
if Thread.current['DRb'] && Thread.current['DRb']['server'] == self
Thread.current['DRb']['stop_service'] = true
else
shutdown
end
end Остановить этот сервер.
# File lib/drb/drb.rb, line 1541 def to_id(obj) return nil if obj.__id__ == front.__id__ @idconv.to_id(obj) end
Преобразует локальный объект в ссылку dRuby.
# File lib/drb/drb.rb, line 1534 def to_obj(ref) return front if ref.nil? return front[ref.to_s] if DRbURIOption === ref @idconv.to_obj(ref) end
Преобразует ссылку dRuby в локальный объект, на который она ссылается.
# File lib/drb/drb.rb, line 1511 def verbose; @config[:verbose]; end
Получить значение, указывает ли сервер на режим подробного вывода.
В режиме подробного вывода неудачные вызовы регистрируются в stdout.
# File lib/drb/drb.rb, line 1506 def verbose=(v); @config[:verbose]=v; end
Set режим подробного вывода.
В режиме подробного вывода неудачные вызовы регистрируются в stdout.
Методы частного экземпляра
# File lib/drb/drb.rb, line 1588
def any_to_s(obj)
"#{obj}:#{obj.class}"
rescue
Kernel.instance_method(:to_s).bind_call(obj)
end Преобразовать объект в строку, предоставив собственную строку представления, если для объекта не определён метод to_s.
# File lib/drb/drb.rb, line 1701
def error_print(exception)
exception.backtrace.inject(true) do |first, x|
if first
$stderr.puts "#{x}: #{exception} (#{exception.class})"
else
$stderr.puts "\tfrom #{x}"
end
false
end
end # File lib/drb/drb.rb, line 1582 def insecure_method?(msg_id) INSECURE_METHOD.include?(msg_id) end
Метод включён в список небезопасных методов?
# File lib/drb/drb.rb, line 1719
def main_loop
client0 = @protocol.accept
return nil if !client0
Thread.start(client0) do |client|
@grp.add Thread.current
Thread.current['DRb'] = { 'client' => client ,
'server' => self }
DRb.mutex.synchronize do
client_uri = client.uri
@exported_uri << client_uri unless @exported_uri.include?(client_uri)
end
loop do
begin
succ = false
invoke_method = InvokeMethod.new(self, client)
succ, result = invoke_method.perform
error_print(result) if !succ && verbose
unless DRbConnError === result && result.message == 'connection closed'
client.send_reply(succ, result)
end
rescue Exception => e
error_print(e) if verbose
ensure
client.close unless succ
if Thread.current['DRb']['stop_service']
shutdown
break
end
break unless succ
end
end
end
end Основной цикл, выполняемый внутренней нитью DRbServer.
Принимает подключение от клиента и запускает свою собственную нить для обработки. Эта нить циклически получает запросы от клиента, вызывает их на локальном объекте и возвращает ответы, до тех пор, пока клиент не закроет соединение или локальный вызов метода не завершится ошибкой.
# File lib/drb/drb.rb, line 1563
def run
Thread.start do
begin
while main_loop
end
ensure
@protocol.close if @protocol
end
end
end Запускает основной цикл DRb в новой нити.
# File lib/drb/drb.rb, line 1548
def shutdown
current = Thread.current
if @protocol.respond_to? :shutdown
@protocol.shutdown
else
[@thread, *@grp.list].each { |thread|
thread.kill unless thread == current # xxx: Thread#kill
}
end
@thread.join unless @thread == current
end
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.