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;
