The HLEB2 framework provides the capability to perform asynchronous requests, which imposes additional requirements on the code. One of the main requirements is to eliminate stored state upon the request's completion.
Stored state can include current user data, request data cache, various forms of memoization, etc.
In programming, memoization is an optimization method that makes already computed data reusable. The approach involves caching the output of a class method and forcing the method to check whether the required computation is already in the cache before computing it.
It is necessary to determine which stored states relate to the request data and which pertain to the operation of the application as a whole. For example, a computed state for general tariff information won't change from request to request, but the selected tariff for each user needs to be reset. During asynchronous requests, the next request might belong to a different user, making it important to clear information about the previous one.
Modern programming practices discourage the use of a state stored as a static class property, but it is often convenient, and concerns about it arise only when transitioning to asynchronous mode.
To facilitate this transition, the HLEB2 framework provides a special interface RollbackInterface with a single static method rollback.
For example, consider a stored state with current user data (simplified code):
To reset the state, the interface RollbackInterface is added, and the method rollback is implemented:
Now, upon the completion of an asynchronous request, the framework will check if the class has the RollbackInterface and execute the reset method rollback. It is important to ensure that the state-resetting method is idempotent and does nothing more. That is, upon repeated execution, the application of the result will not be different.
The need for idempotency is evident from the following, more complex example, where the interface is applied in inheritance (the reset method could be invoked twice):
If you need to execute any action after completing an asynchronous request that is not related to resetting the state in a specific class, you can add it to the rollback method of the App\Bootstrap\ContainerFactory class.