Request Timeout in Business Processes
I want to send requests from custom BP with timeout and be able to understand that timeout event happened.
I thought that I need to implement OnTimeout method in my process (in either caller or callee), however it seems like OnTimeout is never called.
Let's say we have this parent process:
Class Timeout.Parent Extends Ens.BusinessProcess [ ClassType = persistent ]
{
Method OnRequest(pRequest As Ens.StringContainer, Output pResponse As Ens.StringContainer) As %Status {
set sc = ..SendRequestSync("Timeout.Child", pRequest, .pResponse, 5)
if ($$$ISOK(sc) && ('$isObject(pResponse))) {
set text = "Caught timeout"
$$$TRACE(text)
set pResponse = ##class(Ens.StringContainer).%New(text)
}
quit sc
}
Method OnTimeout(request As Ens.StringContainer, ByRef response As Ens.StringContainer, callrequest As Ens.StringContainer, pCompletionKey As %String) As %Status
{
set text = "TIMEOUT PARENT"
$$$TRACE(text)
set response = ##class(Ens.StringContainer).%New(text)
quit $$$OK
}
} And this child process:
Class Timeout.Child Extends Ens.BusinessProcess [ ClassType = persistent ]
{
Method OnRequest(pRequest As Ens.StringContainer, Output pResponse As Ens.StringContainer) As %Status
{
hang 10
set text = "OnRequest CHILD"
$$$TRACE(text)
set pResponse = ##class(Ens.StringContainer).%New(text)
quit $$$OK
}
Method OnTimeout(request As Ens.StringContainer, ByRef response As Ens.StringContainer, callrequest As Ens.StringContainer, pCompletionKey As %String) As %Status
{
set text = "TIMEOUT CHILD"
$$$TRACE(text)
set response = ##class(Ens.StringContainer).%New(text)
quit $$$OK
}
}However, neither OnTimeout method gets called. Why?
I've found a workaround: if SendRequestSync returns $$$OK but response is empty that means we got a timeout error.
Is there a better way to detect timeouts in Sync calls?
Additionally, how can we catch a timeout with async calls? SendRequestAsync doesn't have a timeout parameter at all.
Comments
Hi
You can set a timeout for async calls by calling the SetTimer() method.
See below an example with an async call where the OnTimeout gets called:
Method OnRequest(pRequest As Ens.Request, Output pResponse As Ens.Response) As %Status{ SET t=$$$OK SET t=..SendRequestAsync("BOout",pRequest,1,"RequestCompletionKeyOne",) Set tSC = ..SetTimer("PT10S") Quit t}
Method OnResponse(request As %Library.Persistent, ByRef response As %Library.Persistent, callrequest As %Library.Persistent, callresponse As %Library.Persistent, pCompletionKey As %String) As %Status{ if pCompletionKey="RequestCompletionKeyOne" { $$$TRACE("Response for request with CompletionKey RequestCompletionKeyOne has been received") } Quit $$$OK}Method OnTimeout(request As %Library.Persistent, ByRef response As %Library.Persistent, callrequest As %Library.Persistent, pCompletionKey As %String) As %Status{// Subclass responsibility $$$LOGWARNING(" Timeout Occurred") Quit $$$OK}Regards
Stelios
Thank you!
That's exactly what I need.