jPOS-EE
jPOS-EE copied to clipboard
QRest SendResponse participant does not send response in the prepare method
I have a participant that takes a lot of time. LongRunningParticpant
This LongRunningParticpant
is placed after the SendResponse participant in the txn mgr.
But since the response is only sent in the commit method
It gets sent after the 'LongRunningParticpant'
completes.
Snippet of profiler
<profiler>
prepare: o.j.q.p.Router [0.6/0.6]
prepare: c.o.a.PrepareContext [1.7/2.4]
prepare: c.o.a.InsertRulesInDB [21.8/24.2]
prepare: o.j.q.SendResponse [0.1/24.4]
prepare: c.o.a.TriggerMerchantBlockCacheReload [60241.7/60266.1]
commit: c.o.a.PrepareContext [0.1/60266.2]
commit: c.o.a.InsertRulesInDB [0.0/60266.3]
commit: o.j.q.SendResponse [0.8/60267.1]
commit: c.o.a.TriggerMerchantBlockCacheReload [0.0/60267.1]
end [1.2/60268.3]
</profiler>
So the question is why does the prepare not do anything in the SendResponse participant?
SendResponse
does its main job in the "closing phase" of the two-phase commit protocol.
That could be either a commit
or abort
.
It's good to do it there (and to allow it to happen even if a previous participant aborted it) because that's when you have enough information to create your response.
I don't know what you're doing in your TriggerMerchantBlockCacheReload
.
If it's not related to the transaction, maybe you can choose to
- do the work also during commit/abort (instead of prepare)
- do the work asynchronously, for example by preparing some work payload and sending it to a queue from where a "TriggerMerchantBlockWhatever"
QBean
will be reading in its own thread and doing the work in a concurrent thread, after the transaction has happened.
Thanks for responding @barspi
Could the identical code in commit and abort be moved to prepare and call prepare from abort and remove the commit call?
Option 2 was my backup though the long running participant is ideally part of the transaction :)
Suggestion
public int prepare(long id, Serializable context) {
sendHTTPResponse(context);
return PREPARED | READONLY;
}
protected void sendHTTPResponse(Serializable context) {
Context ctx = (Context) context;
ChannelHandlerContext ch = ctx.get(SESSION);
FullHttpRequest request = ctx.get(REQUEST);
FullHttpResponse response = getResponse(ctx);
sendResponse(ctx, ch, request, response);
}
@Override
public void abort(long id, Serializable context) {
sendHTTPResponse(context);
}
// don't call it in commit