出于无趣的原因,我必须在特定项目中使用jRuby,我们也希望使用Amazon Simple Workflow(SWF) . 我在jRuby部门没有选择,所以请不要说“使用MRI” .
我遇到的第一个问题是jRuby不支持分叉和SWF活动工作者喜欢分叉 . 在浏览SWF ruby库之后,我能够弄清楚如何连接 Logger 并找出如何防止分叉,这非常有用:
AWS::Flow::ActivityWorker.new(
swf.client, domain,"my_tasklist", MyActivities
) do |options|
options.logger= Logger.new("logs/swf_logger.log")
options.use_forking = false
end
这阻止了分叉,但是现在我在SWF源代码中遇到了更多的例外,这些异常与Fibers和不存在的上下文有关:
Error in the poller, exception:
AWS::Flow::Core::NoContextException: AWS::Flow::Core::NoContextException stacktrace:
"aws-flow-2.4.0/lib/aws/flow/implementation.rb:38:in 'task'",
"aws-flow-2.4.0/lib/aws/decider/task_poller.rb:292:in 'respond_activity_task_failed'",
"aws-flow-2.4.0/lib/aws/decider/task_poller.rb:204:in 'respond_activity_task_failed_with_retry'",
"aws-flow-2.4.0/lib/aws/decider/task_poller.rb:335:in 'process_single_task'",
"aws-flow-2.4.0/lib/aws/decider/task_poller.rb:388:in 'poll_and_process_single_task'",
"aws-flow-2.4.0/lib/aws/decider/worker.rb:447:in 'run_once'",
"aws-flow-2.4.0/lib/aws/decider/worker.rb:419:in 'start'",
"org/jruby/RubyKernel.java:1501:in `loop'",
"aws-flow-2.4.0/lib/aws/decider/worker.rb:417:in 'start'",
"/Users/trcull/dev/etl/flow/etl_runner.rb:28:in 'start_workers'"
这是该行的SWF代码:
# @param [Future] future
# Unused; defaults to **nil**.
#
# @param block
# The block of code to be executed when the task is run.
#
# @raise [NoContextException]
# If the current fiber does not respond to `Fiber.__context__`.
#
# @return [Future]
# The tasks result, which is a {Future}.
#
def task(future = nil, &block)
fiber = ::Fiber.current
raise NoContextException unless fiber.respond_to? :__context__
context = fiber.__context__
t = Task.new(nil, &block)
task_context = TaskContext.new(:parent => context.get_closest_containing_scope, :task => t)
context << t
t.result
end
我担心这是同样的分叉问题的另一种风格,也担心我面临着漫长的道路,通过SWF源代码,并解决问题,直到我最终撞到墙壁,我无法解决 .
所以,我的问题是,有没有人真正让jRuby和SWF一起工作?如果是这样,我可以指出哪些步骤和解决方法列表?谷歌搜索“SWF和jRuby”到目前为止还没有发现任何事情,我已经在这个任务的1 1/2天了 .
3 回答
我认为问题可能是aws-flow-ruby不支持Ruby 2.0 . 我发现这是2015年1月22日的PDF .
我对自己的问题有部分答案 . “SWF可以在jRuby上工作”的答案是“是......是的 . ”
实际上,我确实能够让工作流端到端工作(甚至通过JDBC调用数据库,这是我必须这样做的原因) . 所以,这是答案的“是”部分 . 是的,SWF可以用于jRuby .
这是答案中的“ish”部分 .
我上面发布的堆栈跟踪是由于某些活动代码中的问题导致SWF尝试引发ActivityTaskFailedException的结果 . 那部分是我的错 . 什么不是我的错,因为ActivityTaskFailedException的超类中包含以下代码:
当您的活动抛出异常时,您在上面看到的"details"变量将填充一个String . MRI非常乐意将String作为set_backtrace()的参数,但jRuby不是,并且jRuby抛出一个异常,说"details"必须是一个字符串数组 . 这个异常吹嘘了SWF库的所有错误捕获逻辑以及试图与光纤库进行不兼容的代码 . 该代码然后抛出后续异常并完全杀死活动工作者线程 .
因此,只要您的活动和工作流代码永远不会抛出异常,您就可以在jRuby上运行SWF,否则这些异常会终止您的工作线程(这不是SWF工作者的预期行为) . 他们设计的目的是以一种漂亮,可追踪,可恢复的方式将异常传回SWF . 但是,与SWF进行通信的SWF代码本身就具有与jRuby不兼容的代码 .
为了解决这个问题,我修改了AWS :: Flow :: FlowException,如下所示:
希望能帮助处于与我相同情况的人 .
我正在使用JFlow,它允许您使用JRuby启动SWF流活动工作程序 .