我正在为网络自动化开发Rails应用程序。应用程序的一部分包含运行操作的逻辑,部分是操作本身。操作只是一个ruby类,它为网络设备(路由器,交换机等)执行多个命令。
现在,操作只是Rails app repo的一部分。但是为了使开发过程更加灵活,我想解开应用程序和操作。我会有2个回购 - 一个用于app,一个用于操作。应用程序部署将遵循标准过程,但每次将某些内容推送到主服务器时,操作都会同步。更重要的是,我不希望在操作repo更新后重新启动应用程序。
所以我的问题是: 如何排除几个类(或命名空间)在生产Rails应用程序中兑现 - 我的意思是每次我调用这个类时它都会从磁盘重新读取文件。这样做有什么潜在的危险?
一些代码示例:
# Example operation - I would like to add or modify such classes withou
class FooOperation < BaseOperation
def perform(host)
conn = new_connection(host) # method from BaseOperation
result = conn.execute("foo")
if result =~ /Error/
# retry, its known bug in device foo
conn.execute("foo")
else
conn.exit
return success # method from BaseOperation
end
end
end
# somewhere in admin panel I would do so:
o = Operations.create(name: "Foo", class_name: "Foo")
o.id # => 123 # for next example
# Ruby worker which actually runs an operation
class OperationWorker
def perform(operation_id, host)
operation = Operation.find(operation_id)
# here, everytime I load this I want ruby to search for implementation on filesystem, never cache
klass = operation.class_name.constantize
class.new(host).perform #
end
end
答案 0 :(得分:0)
我认为你对ruby代码加载和解释的工作原理有很多误解!
rails在开发时重新加载类的事实是一种&#34; hack&#34;让您在服务器已经加载,解析和执行应用程序的部分时迭代代码。 为了做到这一点,它必须实现一些魔法来卸载你的代码并在更改时重新加载它的一部分。
所以如果你想在执行&#34;操作时想要拥有最新的代码&#34;你可能最好通过产生一个新的过程。这将保证在以空白状态执行时,您的新代码将被正确读取和解析。
您可以做的另一件事是使用load
而不是require
,因为它实际上会在后续请求中重新读取源代码。你必须记住,后来对load
的调用只是添加到ruby VM中已有的代码中。所以你需要确保每个更改都与已加载的代码兼容。
这可以通过一些聪明的instance_eval
技巧来规避,但我不确定这是你想要的......