класс DRb::DRbServer
Класс, представляющий экземпляр сервера drb.
Сервер DRbServer должен быть запущен в локальном процессе, прежде чем можно будет принять входящие вызовы dRuby или передать локальные объекты как ссылки dRuby в удаленные процессы, даже если эти локальные объекты никогда фактически не вызываются удалённо. Вам не нужно запускать DRbServer в локальном процессе, если вы только делаете исходящие вызовы dRuby, передавая закодированные параметры.
Если не используются несколько серверов, локальный DRbServer обычно запускается путём вызова DRb#start_service.
Константы
- INSECURE_METHOD
-
Список небезопасных методов.
Эти методы недоступны для вызова через dRuby.
Атрибуты
Настройка данного DRbServer
Объект front сервера DRbServer.
Этот объект получает удалённые вызовы методов, сделанные для URI сервера URI в одиночку, с идентификатором объекта.
Уровень безопасности для этого сервера. Это число, соответствующее $SAFE.
По умолчанию #safe_level равен 0.
Основной поток данного DRbServer.
Это поток, который прослушивает и принимает подключения от клиентов, а не обрабатывает сеанс запроса-ответа для каждого клиента.
URI данного DRbServer.
Публичные методы класса
# File lib/drb/drb.rb, line 1303 def self.default_acl(acl) @@acl = acl end
Установить список контроля доступа по умолчанию на acl. Список контроля доступа по умолчанию (ACL) — nil.
См. также DRb::ACL и new()
# File lib/drb/drb.rb, line 1289 def self.default_argc_limit(argc) @@argc_limit = argc end
Установить значение по умолчанию для параметра :argc_limit.
См. new(). Начальное значение по умолчанию — 256.
# File lib/drb/drb.rb, line 1310 def self.default_id_conv(idconv) @@idconv = idconv end
Установить значение по умолчанию для параметра :id_conv.
См. new(). Начальное значение по умолчанию — экземпляр DRbIdConv.
# File lib/drb/drb.rb, line 1296 def self.default_load_limit(sz) @@load_limit = sz end
Установить значение по умолчанию для параметра :load_limit.
См. new(). Начальное значение по умолчанию — 25 МБ.
# File lib/drb/drb.rb, line 1317 def self.default_safe_level(level) @@safe_level = level end
Установить уровень безопасности по умолчанию на level. Уровень безопасности по умолчанию — 0.
См. new для получения дополнительной информации.
# File lib/drb/drb.rb, line 1391
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]
@safe_level = @config[:safe_level]
@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.
- :safe_level
-
Уровень безопасности DRbServer. Атрибут устанавливает $SAFE для методов, выполняемых в main_loop. По умолчанию 0.
Значения по умолчанию для этих параметров можно изменить на уровне класса с помощью методов default_argc_limit, default_load_limit, default_acl, default_id_conv и verbose=.
Если config_or_acl не является хэшем, но не nil, предполагается, что это список контроля доступа для этого сервера. См. параметр :tcp_acl для получения дополнительных сведений.
Если в данный момент ни один другой сервер не установлен в качестве основного, этот сервер станет основным.
Сервер сразу же начнёт работу в собственном потоке.
# File lib/drb/drb.rb, line 1329 def self.verbose @@verbose end
Получить значение по умолчанию параметра :verbose.
# File lib/drb/drb.rb, line 1324 def self.verbose=(on) @@verbose = on end
Установить значение по умолчанию параметра :verbose.
См. new(). Начальное значение по умолчанию — false.
Общедоступные методы экземпляров
# File lib/drb/drb.rb, line 1453 def alive? @thread.alive? end
Работает ли этот сервер?
# File lib/drb/drb.rb, line 1541
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)
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
end Проверка, что метод вызываем через dRuby.
obj — объект, на котором мы хотим вызвать метод. msg_id — имя метода в формате символа.
Если метод является небезопасным (см. insecure_method?), выбрасывается SecurityError. Если метод является закрытым или не определён, выбрасывается NameError.
# File lib/drb/drb.rb, line 1458 def here?(uri) @exported_uri.include?(uri) end
Является ли uri URI этого сервера?
# File lib/drb/drb.rb, line 1463
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 1480 def to_id(obj) return nil if obj.__id__ == front.__id__ @idconv.to_id(obj) end
Преобразовать локальный объект в ссылку dRuby.
# File lib/drb/drb.rb, line 1473 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 1450 def verbose; @config[:verbose]; end
Получить, находится ли сервер в режиме подробной информации.
В режиме подробной информации неудачные вызовы регистрируются в stdout.
# File lib/drb/drb.rb, line 1445 def verbose=(v); @config[:verbose]=v; end
Установить режим подробной информации.
В режиме подробной информации неудачные вызовы регистрируются в stdout.
Закрытые методы экземпляров
# File lib/drb/drb.rb, line 1527
def any_to_s(obj)
obj.to_s + ":#{obj.class}"
rescue
sprintf("#<%s:0x%lx>", obj.class, obj.__id__)
end Преобразовать объект в строку, предоставив собственное представление, если для объекта не определён to_s.
# File lib/drb/drb.rb, line 1640
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 1521 def insecure_method?(msg_id) INSECURE_METHOD.include?(msg_id) end
Включён ли метод в список небезопасных методов?
# File lib/drb/drb.rb, line 1658
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
client.send_reply(succ, result)
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 1502
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 1487
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.