Open eguzki opened 3 weeks ago
Not for today. I would love your thoughts @didierofrivia
I think at the moment there's no reason for considering a refactor... specially after https://github.com/Kuadrant/wasm-shim/pull/125 that is solving the use cases you presented with the e2e tests. However, it will be definitely good to review not only the OperationDispatcher but the whole of the wasm shim.... starting from it's name. We might need to present real use cases and/or performance/complexity tests in order to not be biased by our assumptions on hypothetical use cases and workflows. However, these kind of analyses are good and we could revisit it after GA in order to assess its viability 👍🏼
The current implementation works (famous last words). However, it does not fit well with the lifetime of the tasks, which may (or may not) run (one or multiple) GRPC requests.
Description of the workflow
create_http_context
, which has the lifetime of one single HTTP request. It is not being reused for multiple HTTP requests re-using the same connection.hostcalls::send_http_response(status_code: 429, response_headers, body: Some(b"Too Many Requests\n"))
failureMode
.The high level structure
The GRPC operation
The GRPC operations are started and then they can run N GRPC requests. Each time a GRPC request is done, the operation will be waiting for response that will be signaled with the
on_grpc_response
.The operation result has the following meaning:
start
andon_grpc_response
should not be called.on_grpc_response
will eventually be calledstart
andon_grpc_response
should not be called.When something failed on the operation work, the operation should check FailureMode. If failure mode is
deny
, then the operation should send HTTP responseself.send_http_response(status_code: 500, headers: vec![], body: Some(b"Internal Server Error.\n"))
or whatever it needs to be send. For instance, on over the limit in a rate limiting action, it should sendhostcalls::send_http_response(status_code: 429, response_headers, body: Some(b"Too Many Requests\n"))
. Then return OperationResult::FailedOn the other hand, if failure mode is
allow
, the operation should decide what to do. It can either beOperationResult::Failed
orOperationResult::Done
, but neverOperationResult::Wait
The operation dispatcher
From the Wasm HTTPContext, on
http_request_headers
, the operation dispatcher should be populated with the action sets and those which conditions do not apply, then filtered out. Then, therun
method should be called and map RunAction toproxy_wasm::types::Action
. The mapping should be straightforwardFrom the Wasm HTTPContext, on
on_grpc_call_response
, theon_grpc_response
method should be called. That should update the internal status of the current operation waiting for GRPC response. Then, resume dispatcher work running againrun
method. Fromon_grpc_call_response
, it is needed to know whether the dispatcher is done and then callself.resume_http_request()
method. This is what RunAction will tell.hostcalls::send_http_response(status_code: 429, response_headers, body: Some(b"Too Many Requests\n"))
self.resume_http_request()
When
run
method it called, internally, the operations will be executed. When one of the operations returns "Fail" state, from the dispatcher perspective, the entire workflow should be halted and the return value should be "RunAction::DoneFailed. When ALL the operations are done and the queue is empty, the return value should be "RunAction::DoneOK
. When one of the operations returnOperationResult::Wait
, the dispatcher should return RunAction::Wait.When
on_grpc_response
is called, the dispatcher knows which operation is waiting (the first of the list) and can call itson_grpc_response
method. Then. waitrun
method to be called.Operation dispatcher state machine