Skip to content

Should Connection#pipeline have the same retry logic as #run and #multi? #71

Description

@robacarp

Honeybadger captured an error recently for me which was caused by a connection blip between the mosquito worker and Redis. It could have been a transient network failure or something else, but the exception thrown was:

Redis::Pipeline::ResolutionError: Failed reading pipeline item 0: "Connection closed"

bin/worker in 'raise<Redis::Pipeline::ResolutionError>:NoReturn':0 in **unknown**
bin/worker in 'Redis::Pipeline#commit:Array(Array(Redis::Value) | Int64 | Redis::Error+ | String | Nil)':0 in **unknown**
bin/worker in 'Mosquito::RedisBackend::Queue#enqueue<Mosquito::JobRun>:Mosquito::JobRun':0 in **unknown**
bin/worker in 'Mosquito::Queue#enqueue<Mosquito::JobRun>:Mosquito::JobRun':0 in **unknown**

That led me to some investigating about what Mosquito should do in this situation. What happened is that the mosquito worker crashed and was rebooted. That's maybe the best case, but the error message was initially opaque to me.

Anyway, connection run and multi both have similar logic but pipeline does not. I thought that might be by design, but I'm unsure. It seems almost identically risky to try to retry a multi as a pipeline.

Connection#pipeline

    def pipeline(&)
      pipeline = Pipeline.new(self)
      error = nil
      begin
        yield pipeline
      rescue ex
        error = ex
      end

      flush
      result = pipeline.commit

      if error
        raise error
      else
        result
      end
    end

Connection#run

    def run(command, retries = 5) : Value
      start = instant_time

      loop do
        @writer.encode command
        flush
        return read
      rescue ex : IO::Error
        if retries > 0
          retries -= 1
          initialize @uri
        else
          raise ex
        end
     # ...

Connection#multi

    def multi(retries = 5, &)
      loop do
        txn = Transaction.new(self)

        begin
          txn.start!
          yield txn
        rescue ex
          txn.discard
          raise ex
        end
      rescue ex : IO::Error
        if retries > 0
          retries -= 1
          initialize @uri
   # ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions