redis实现异步任务队列
先说思路:
将任务对象序列为JSON字符串,然后推入REDIS缓存,这叫入队。
通过独立的工作线程从REDIS拉出一个任务,这叫出队,工作线程将JSON字符串还原为任务对象,然后对这个任务对象进行处理,并取得执行结果。
整个过程是全异步执行的,所以叫异步任务队列。
下面附上演示代码。
1)任务对象定义
type TJob = class private FReplyTo: String; procedure SetReplyTo(const Value: String); public property ReplyTo: String read FReplyTo write SetReplyTo; end; TEvalJob = class(TJob) private FExpression: String; procedure SetExpression(const Value: String); public property Expression: String read FExpression write SetExpression; end; TDatabaseJob = class(TJob) private FProcedureName: String; procedure SetProcedureName(const Value: String); public property ProcedureName: String read FProcedureName write SetProcedureName; end;
2)入队
procedure TMainForm.Button1Click(Sender: TObject); var lRedis: IRedisClient; lJob: TEvalJob; lJobString: string; begin lRedis := NewRedisClient(REDIS_HOSTNAME); lJob := TEvalJob.Create; try lJob.ReplyTo := 'replies:' + FUserName; lJob.Expression := Edit1.Text; lJobString := TJson.ObjectToJsonString(lJob); lRedis.LPUSH('jobs', lJobString); finally lJob.free; end; end;
3)出队并执行
procedure TMainForm.Timer1Timer(Sender: TObject); var lJobj: TJSONObject; lExpression, lRes: string; lResponse: string; begin if FRedis.RPOP('replies:' + FUserName, lResponse) then begin lJobj := TJSONObject.ParseJSONValue(lResponse) as TJSONObject; try lExpression := lJobj.GetValue<TJSONString>('expression').Value; lRes := lJobj.GetValue<TJSONString>('result').Value; Memo1.Lines.Add(Format('Response: %s = %s', [lExpression, lRes])); finally lJobj.free; end; end; end;