Waiting for a Job: a worked example
A common integration is "reload the data, then use it": trigger a Bragi Job, wait for it to finish, then carry on against the freshly loaded warehouse. Job Callbacks describes the mechanism; this is one way to build the calling side, in C# on ASP.NET Core.
There are three pieces:
A registry of requests currently waiting for a run to finish
An endpoint Bragi posts the outcome to, which releases the matching wait
The caller, which registers a wait, triggers the Job and awaits the result
The payload
Bragi posts the JSON described in Job Callbacks. Model whichever fields you need:
Bragi serialises camelCase, which is the default for ASP.NET Core, so no configuration is needed.
The registry
The callback arrives on a different request to the one waiting, so the two need somewhere to meet. CallerReference is what ties them together: a value the caller invents, hands to Bragi, and gets back on the callback.
Register it as a singleton.
The endpoint
Two things to be deliberate about:
Answer
200either way. An unknown reference is not a delivery failure, and returning an error only makes Bragi retry something that cannot succeed.The endpoint is anonymous. Bragi sends no credentials, so the caller reference stands in for them: it is a GUID minted per wait, is only valid while that wait is outstanding, and the most an unauthenticated caller could do with a guessed value is release one wait early. If your application requires authentication by default, this route needs an explicit exemption, and behind IIS it also needs Anonymous Authentication enabled for the path.
The caller
RunJobNow here is a thin wrapper over the API call described in Bragi API, passing callbackUrl and callbackReference as query string parameters.
Points worth getting right
Always release the wait. The finally matters. Without it a timed out request leaves an entry in the dictionary forever, and a long running application slowly fills memory with waits nobody is on.
Choose a timeout you can defend. It has to exceed the Job's realistic worst case, or a slow night looks like a failure. Decide deliberately what happens when it expires: carrying on against data that may be half loaded is sometimes worse than returning nothing.
A success response does not always mean a new run. If the Job is already queued, Bragi attaches your callback to the queued run. If it has already started, your callback waits for the next run, which Bragi queues once the current one finishes. Either way the message says which, and the run your callback reports on always started after your call, so data you wrote beforehand is included. Allow for that in your timeout: the wait can cover the run in progress as well as your own. See Job Callbacks for the full set of outcomes.
Consider a no-callback fallback. If the calling system may be deployed against a Bragi that cannot reach it, make the callback URL configuration optional: with it set, wait; without it, trigger and carry on, exactly as a caller behaved before callbacks existed. Send no callback parameters at all in that mode so the request is identical to the old one.