anchor.diff:          opts: Map<string,string> option
           _progress: int
       }
  +    member this.lockKey () = this.queue.toKey((this.jobId.ToString ()) + ":lock")
       member this.toData () =  
           let jsData = JsonConvert.SerializeObject (this.data)
           let jsOpts = JsonConvert.SerializeObject (this.opts)
  
positive.code:     member this.remove () = async { raise (NotImplementedException ()) }
      member this.progress cnt = async { raise (NotImplementedException ()) }
      member this.takeLock (token, ?renew) = async {
              let lockKey = this.queue.toKey((this.jobId.ToString ()) + ":lock")
              let nx = match renew with 
                       | Some x -> When.NotExists
                       | None -> When.Always
          
              let value = (token.ToString ()) |> toValueStr
              let client:IDatabase = this.queue.client
              return! client.StringSetAsync (lockKey, value, Nullable (TimeSpan.FromMilliseconds (LOCK_RENEW_TIME)), nx) |> Async.AwaitTask
          }
      static member create (queue, jobId, data:'a, opts) = 
          async { 
              let job = { queue = queue; data = data; jobId = jobId; opts = opts; _progress = 0 }
  
negative.code:     let token = Guid.NewGuid ()
      let event = new Event<OxenEvent<'a>> ()
      let processJob job = async { 
              // if paused then return else
              // processing <- true; job.renewLock(); renewlocktimeout <- settimeout;
              //try -> handler(); job.moveToCompleted; emit "completed"
              // catch -> job.moveToFailed; job.releaseLock; emit "failed"
              //cleartimeout(lockrenewtimeout); processing <- false 
              ()
          }
      let processStalledJob (job:Job<'a>) = 
          async { 
  