класс DRb::DRbServer
Class представляющий экземпляр сервера drb.
Сервер DRbServer должен работать в локальном процессе, прежде чем будут приняты какие-либо входящие вызовы dRuby, или любые локальные объекты могут быть переданы как ссылки dRuby в удалённые процессы, даже если эти локальные объекты никогда фактически не вызываются удалённо. Вам не нужно запускать DRbServer в локальном процессе, если вы только делаете исходящие вызовы dRuby, передавая сериализованные параметры.
Если не используются несколько серверов, локальный DRbServer обычно запускается вызовом DRb.start_service.
Константы
- INSECURE_METHOD
-
Список небезопасных методов.
Эти методы недоступны для вызова через dRuby.
Атрибуты
Конфигурация данного DRbServer
Объект front сервера DRbServer.
Этот объект получает удалённые вызовы методов, выполненные на сервере 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 — имя метода как Symbol.
Если метод является небезопасным (см. 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
Получение значения, указывающего на режим подробных сообщений сервера.
В режиме подробных сообщений информация о неудачных вызовах записывается в стандартный вывод.
# File lib/drb/drb.rb, line 1445 def verbose=(v); @config[:verbose]=v; end
Set режим подробных сообщений.
В режиме подробных сообщений информация о неудачных вызовах записывается в стандартный вывод.
Приватные методы экземпляров
# 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 1646
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 1664
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.