класс 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 1450
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://<имя_хоста>:<порт>', где <имя_хоста> — имя локального компьютера. Если равно 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 1393 def self.verbose @@verbose end
Получает значение по умолчанию параметра :verbose.
# File lib/drb/drb.rb, line 1388 def self.verbose=(on) @@verbose = on end
Set значение по умолчанию параметра :verbose.
См. new(). Начальное значение по умолчанию - false.
Методы публичного экземпляра
# File lib/drb/drb.rb, line 1505 def alive? @thread.alive? end
Этот сервер работает?
# File lib/drb/drb.rb, line 1593
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 1510 def here?(uri) @exported_uri.include?(uri) end
Является ли uri URI для этого сервера?
# File lib/drb/drb.rb, line 1515
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 1532 def to_id(obj) return nil if obj.__id__ == front.__id__ @idconv.to_id(obj) end
Преобразовать локальный объект в ссылку dRuby.
# File lib/drb/drb.rb, line 1525 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 1502 def verbose; @config[:verbose]; end
Получить состояние подробной информации о работе сервера.
В режиме подробной информации сообщения об ошибках вывода операций будут выводиться в stdout.
# File lib/drb/drb.rb, line 1497 def verbose=(v); @config[:verbose]=v; end
Set режим подробной информации.
В режиме подробной информации сообщения об ошибках вывода операций будут выводиться в stdout.
Приватные методы экземпляра
# File lib/drb/drb.rb, line 1579
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 1695
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 1573 def insecure_method?(msg_id) INSECURE_METHOD.include?(msg_id) end
Метод включён в список небезопасных методов?
# File lib/drb/drb.rb, line 1713
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
_last_invoke_method = nil
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
_last_invoke_method = invoke_method
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 1554
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 1539
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–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.