title: ActiveJob perform_later from inside Redis subscription block
body: <p>I want to use the ruby redis client to subscribe to a channel. When subscription was successful I want to start an ActiveJob (Sidekiq is used) job using <code>perform_later</code>. This Job will then do some work and produce a result which will be published to the <code>channel</code> Redis channel.
  This produces the following error:</p>
  <pre><code>Processing by Api::LocationController#yyy as */*
    Parameters: {&quot;zip_code&quot;=&gt;&quot;503400&quot;}
  [ActiveJob] Failed enqueuing XXXJob to Sidekiq(default): NoMethodError (undefined method `call_pipeline' for #&lt;Redis::SubscribedClient:0x00007fd9222cdf78 @client=#&lt;Redis::Client:0x00007fd921e1b890 @options={:url=&gt;&quot;redis://localhost?db=xxx&quot;, :scheme=&gt;&quot;redis&quot;, :host=&gt;&quot;localhost&quot;, :port=&gt;6379, :path=&gt;nil, :read_timeout=&gt;0, :write_timeout=&gt;5.0, :connect_timeout=&gt;5.0, :timeout=&gt;5.0, :username=&gt;nil, :password=&gt;nil, :db=&gt;0, :driver=&gt;Redis::Connection::Ruby, :id=&gt;nil, :tcp_keepalive=&gt;0, :reconnect_attempts=&gt;1, :reconnect_delay=&gt;0.0, :reconnect_delay_max=&gt;0.5, :inherit_socket=&gt;false, :logger=&gt;nil, :sentinels=&gt;nil, :role=&gt;:master, :_parsed=&gt;true}, @reconnect=true, @logger=nil, @connection=#&lt;Redis::Connection::Ruby:0x00007fd921df08c0 @sock=#&lt;Redis::Connection::TCPSocket:fd 26&gt;&gt;, @command_map={}, @pending_reads=-3, @connector=#&lt;Redis::Client::Connector:0x00007fd921e1a2d8 @options={:url=&gt;&quot;redis://localhost?db=xxx&quot;, :scheme=&gt;&quot;redis&quot;, :host=&gt;&quot;localhost&quot;, :port=&gt;6379, :path=&gt;nil, :read_timeout=&gt;5.0, :write_timeout=&gt;5.0, :connect_timeout=&gt;5.0, :timeout=&gt;5.0, :username=&gt;nil, :password=&gt;nil, :db=&gt;0, :driver=&gt;Redis::Connection::Ruby, :id=&gt;nil, :tcp_keepalive=&gt;0, :reconnect_attempts=&gt;1, :reconnect_delay=&gt;0.0, :reconnect_delay_max=&gt;0.5, :inherit_socket=&gt;false, :logger=&gt;nil, :sentinels=&gt;nil, :role=&gt;:master, :_parsed=&gt;true}&gt;, @pid=54943&gt;&gt;)
  Completed 500 Internal Server Error in 26ms (Allocations: 2374)
  
  
    
  NoMethodError (undefined method `call_pipeline' for #&lt;Redis::SubscribedClient:0x00007fd9222cdf78 @client=#&lt;Redis::Client:0x00007fd921e1b890 @options={:url=&gt;&quot;redis://localhost?db=xxx&quot;, :scheme=&gt;&quot;redis&quot;, :host=&gt;&quot;localhost&quot;, :port=&gt;6379, :path=&gt;nil, :read_timeout=&gt;5.0, :write_timeout=&gt;5.0, :connect_timeout=&gt;5.0, :timeout=&gt;5.0, :username=&gt;nil, :password=&gt;nil, :db=&gt;0, :driver=&gt;Redis::Connection::Ruby, :id=&gt;nil, :tcp_keepalive=&gt;0, :reconnect_attempts=&gt;1, :reconnect_delay=&gt;0.0, :reconnect_delay_max=&gt;0.5, :inherit_socket=&gt;false, :logger=&gt;nil, :sentinels=&gt;nil, :role=&gt;:master, :_parsed=&gt;true}, @reconnect=true, @logger=nil, @connection=#&lt;Redis::Connection::Ruby:0x00007fd921df08c0 @sock=nil&gt;, @command_map={}, @pending_reads=-3, @connector=#&lt;Redis::Client::Connector:0x00007fd921e1a2d8 @options={:url=&gt;&quot;redis://localhost?db=xxx&quot;, :scheme=&gt;&quot;redis&quot;, :host=&gt;&quot;localhost&quot;, :port=&gt;6379, :path=&gt;nil, :read_timeout=&gt;5.0, :write_timeout=&gt;5.0, :connect_timeout=&gt;5.0, :timeout=&gt;5.0, :username=&gt;nil, :password=&gt;nil, :db=&gt;0, :driver=&gt;Redis::Connection::Ruby, :id=&gt;nil, :tcp_keepalive=&gt;0, :reconnect_attempts=&gt;1, :reconnect_delay=&gt;0.0, :reconnect_delay_max=&gt;0.5, :inherit_socket=&gt;false, :logger=&gt;nil, :sentinels=&gt;nil, :role=&gt;:master, :_parsed=&gt;true}&gt;, @pid=54943&gt;&gt;):
  
    
  app/controllers/api/location_controller.rb:10:in `block (3 levels) in yyy'
  app/controllers/api/location_controller.rb:8:in `block in yyy'
  app/controllers/api/location_controller.rb:5:in `yyy'
  </code></pre>
  <p>The <code>yyy</code> function is part of a controller that gets called on a <code>GET</code> request:</p>
  <pre class="lang-rb prettyprint-override"><code>  def yyy
      REDIS_POOL.with { |r|
        data = r.get(&quot;key&quot;)
        if data.nil?
          r.subscribe(&quot;channel&quot;) { |on|
            on.subscribe {
              XXXJob.perform_later(params)
            }
            on.message { |_, message|
              puts message
              render json: message
              r.unsubscribe(&quot;channel&quot;)
            }
          }
        else
          render json: data
        end
      }
    end
  </code></pre>
  <p>It seems to me like there's some context being lost from the Redis <code>subscribe</code> block which is important for the <code>perform_later</code> function. The same code works if I move the <code>XXXJob.perform_later(params)</code> call above the <code>r.subscribe(&quot;channel&quot;)</code> call and thus outside of the block. I however want to make sure that the job is only started after the subscription to the Redis channel was successful. Is there any way to achieve this?</p>