首页 文章

Amazon Simple Workflow(SWF)可以与jRuby一起使用吗?

提问于
浏览
0

出于无趣的原因,我必须在特定项目中使用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 回答

  • 0

    我认为问题可能是aws-flow-ruby不支持Ruby 2.0 . 我发现这是2015年1月22日的PDF .

    1.2.1经过测试的Ruby运行时Ruby的AWS Flow Framework已经过官方的Ruby 1.9运行时测试,也称为YARV . 其他版本的Ruby运行时可能有效,但不受支持 .

  • 0

    我对自己的问题有部分答案 . “SWF可以在jRuby上工作”的答案是“是......是的 . ”

    实际上,我确实能够让工作流端到端工作(甚至通过JDBC调用数据库,这是我必须这样做的原因) . 所以,这是答案的“是”部分 . 是的,SWF可以用于jRuby .

    这是答案中的“ish”部分 .

    我上面发布的堆栈跟踪是由于某些活动代码中的问题导致SWF尝试引发ActivityTaskFailedException的结果 . 那部分是我的错 . 什么不是我的错,因为ActivityTaskFailedException的超类中包含以下代码:

    def initialize(reason = "Something went wrong in Flow",
       details = "But this indicates that it got corrupted getting out")
       super(reason)
       @reason = reason
       @details = details
       details = details.message if details.is_a? Exception
       self.set_backtrace(details)
    end
    

    当您的活动抛出异常时,您在上面看到的"details"变量将填充一个String . MRI非常乐意将String作为set_backtrace()的参数,但jRuby不是,并且jRuby抛出一个异常,说"details"必须是一个字符串数组 . 这个异常吹嘘了SWF库的所有错误捕获逻辑以及试图与光纤库进行不兼容的代码 . 该代码然后抛出后续异常并完全杀死活动工作者线程 .

    因此,只要您的活动和工作流代码永远不会抛出异常,您就可以在jRuby上运行SWF,否则这些异常会终止您的工作线程(这不是SWF工作者的预期行为) . 他们设计的目的是以一种漂亮,可追踪,可恢复的方式将异常传回SWF . 但是,与SWF进行通信的SWF代码本身就具有与jRuby不兼容的代码 .

    为了解决这个问题,我修改了AWS :: Flow :: FlowException,如下所示:

    def initialize(reason = "Something went wrong in Flow",
                     details = "But this indicates that it got corrupted getting out")
        super(reason)
        @reason = reason
        @details = details
        details = details.message if details.is_a? Exception
        details = [details] if details.is_a? String
        self.set_backtrace(details)
      end
    

    希望能帮助处于与我相同情况的人 .

  • 0

    我正在使用JFlow,它允许您使用JRuby启动SWF流活动工作程序 .

相关问题