Runtime
This page serves as an overview of the Bistro runtime, its lifecyles and components
Contents |
Main Components
The Bistro runtime operates using 3 main components
- The Controller Dispatcher (IControllerDispatcher) for computing execution chains
- The Controller Manager (IControllerManager) for maintaining the full set of available controllers
- Controller Handlers (IControllerHandler) for marshalling Controller instances
Each of these components can be substituted out via the configuration options available for the bistro runtime.
The rest of this article will focus on the various flows within the bistro runtime, and how they consume the components outlined above. For documentation on customizing the individual components, or their default implementations, please consult the Bistro Class Library
Bistro Application Lifecycle
| The Bistro runtime is represented at the top level via the Application Class. This class is responsible for bootstrapping the Bistro runtime, and is in turn initialized through the Bistro Module as pictured.
Each step is driven through the default-first configuration setting. The application class and factories can be overriden. Typically, only the definition of an additional component, one not already covered by one of the factories present, would require the extension or re-definition of the application class. |
Error creating thumbnail: convert.exe: unable to open image `C:\inetpub\wwwroot\bistro/images/1/15/B_app_lc.png': No such file or directory @ error/blob.c/OpenBlob/2642. convert.exe: unable to open file `C:\inetpub\wwwroot\bistro/images/1/15/B_app_lc.png' @ error/png.c/ReadPNGImage/3733. convert.exe: no images defined `C:\Windows\TEMP/transform_6431abbb5cd3-1.png' @ error/convert.c/ConvertImageCommand/3044. |
Bistro Request Lifecycle
The bistro runtime integrates with the ASP.NET pipeline to implement it's functionality. Once invoked, the runtime goes through the following steps:
|
Error creating thumbnail: convert.exe: unable to open image `C:\inetpub\wwwroot\bistro/images/b/b0/B_rqst.png': No such file or directory @ error/blob.c/OpenBlob/2642. convert.exe: unable to open file `C:\inetpub\wwwroot\bistro/images/b/b0/B_rqst.png' @ error/png.c/ReadPNGImage/3733. convert.exe: no images defined `C:\Windows\TEMP/transform_1b7a790b7c56-1.png' @ error/convert.c/ConvertImageCommand/3044. |
ASP.NET Interception
The bistro runtime intergrates with asp.net via a module and a handler. The module, executing for all requests, determines if the inbound request is a bistro method invocation (as determined by url recognition rules). Each module Init() invocation determines whether the bistro application class has been instantiated, and does so if it has not. From that point forward, each module will reference the same instance of the application class. Do note that the invocation of the bistro handler is done through the HttpContext.RemapHandler() method, which requires .NET 3.5 SP1+ or 2.0 SP2+.
Once the handler has been invoked, the bistro pipeline begins as depicted above. |
Error creating thumbnail: convert.exe: unable to open image `C:\inetpub\wwwroot\bistro/images/3/3d/B_asp_lce.png': No such file or directory @ error/blob.c/OpenBlob/2642. convert.exe: unable to open file `C:\inetpub\wwwroot\bistro/images/3/3d/B_asp_lce.png' @ error/png.c/ReadPNGImage/3733. convert.exe: no images defined `C:\Windows\TEMP/transform_1de67f3e70aa-1.png' @ error/convert.c/ConvertImageCommand/3044. |
Controller Chain Computation
Controller chain computation is delegated to the current active implementation of IControllerDispatcher. The default implementation works as follows:
- For each bind point in the full list, a determination is made whether the bind point applies to this request
- The set of matched bind points is then sorted, according to the BindType specified (currently
Before, PayloadandAfter - A secondary sort is then applied, enforcing dependencies
- Finally, all controllers identified as
securitycontrollers, are moved to the top of the execution chain, regardless ofBindTypeor resource rules. If a security controller has a dependency on a standard controller, a runtime exception is generated.
Once computed, the list is returned to the caller, as an ordered list of controller invocation infos. This structure encodes which specific bind point on the controller class matched the inbound request, and the parameter values that were supplied to it.
- Something to remember
- The controller dispatcher is expected to be a thread-safe singleton implementation. It is used during bootstrapping to register the full list of controllers, and is expected to retain this information.
Security
The runtime expects the controller chain returned to have all security controllers, if any, at the top. When processing the execution chain, the request is not considered authorized until all security controllers are processed.
- For all security controllers, the
ProcessRequestmethod is invoked first, followed by theHasAccessmethod. - Security controllers are allowed to have dependencies amongst themselves
- They are also allowed to provide data to non-security controllers.
As security policy is being applied, the full set of security controllers will be processed prior to a determination being made, as a subsequent controller can override a failure of a previous one. Each controller is provided with a list of security demands that have currently failed, and security controllers are allowed to remove elements from this list. Specifically, if a standard SecurityController marked with Deny("admin") fails, a subsequent Allow("admin") will need to override this determination, and will do so by removing the failure from the list.
Once the full list of security controllers has been processed, the list of failures will be examined. If there is at least one element, the request is considered unauthorized, and the FailAction is taken
- If the
FailActionisRedirect, an immediate Transfer is requested to the redirect destination - If the
FailActionisFail, aHTTP:403is returned to the browser.
If there are no failures, the rest of the controller chain is processed.
Controller Execution
Controller execution consists of the following steps
- An instance of the controller is obtained.
- This instance is retrieved through the
ControllerManager, which in turn uses aControllerHandlerto both retrieve, and populate an instance of the requested controller. - The controller is returned with all of it's resource and parameter fields/properties populated with data from the context and session
- This instance is retrieved through the
- The
ProcessRequestmethod is invoked - The controller is then returned to the
ControllerManager, which in turn uses theControllerHandlerto read the data from the controller and back onto the respective targets (session, request, etc.). The handler will then invoke theRecyclemethod for controllers that have been marked asReusable
During execution, controllers may use the IExecutionContext.Transfer method to request the execution of another bistro method. This will be done after all controllers in the current execution chain have been processed. The transfer requests will not be queued, and the last transfer request made will be the one to be executed.
If a transfer request is made, the bistro handler will re-start the pipeline from the beginning, recomputing the execution chain, and re-validating security policy, as a different policy may apply to the new request.
If a controller needs to stop execution, a WebException can be thrown. This will stop the execution of the controller chain, and return the http status code and message to the browser.
Output
Output in bistro is handled via controllers provided by the system. Currently there are two controllers for this
- The RenderingController provides integration with various templating engines, and typically provides HTML output. It reads the
RenderTargetfield on the context, and uses that as the name of the template to invoke.- This controller will not execute if a transfer request is pending
- This controller will not execute if the current ReturnType is not
ReturnType.Template
- The ReturnTypesController provides structured data output, such as XML and JSON. This controller will read the various fields set by the
IResponse.ReturnXXXmethods.- This controller will not execute if a transfer request is pending
- This controller will not execute if the current
ReturnTypeisReturnType.Template
Exceptions
With the exception of the WebException, exceptions raised during request processing are allowed to bubble up
- Future direction
- Runtime support for centralized exception handling will be provided in an upcoming release