With newer, modern hardware systems, it is likely that they will contain either multiple physical processors or a single physical processor with multiple cores. When writing applications with these systems as the target platform, it is often a good idea to utilize more than a single process within the application. Why is it that multiple processes make sense within a single application? One may be inclined to think of the concept of a process as being designated for a single running application, or a one-to-one cardinality if you will. On top of moving away from the comfortable idea of a single process for a single application that so many developers are used to, there is also the messy problem of inter-process communication. This particular problem isn't quite as bad as it is made out to be. We just need to use the appropriate abstractions on top of the inter-process communication functionality. Going back to the question of why it is a good idea in the first place, the chief benefit of using multiple processes within a single application is the performance gains. While the same application concurrency logic implemented using threads will offer better responsiveness, the multiprocessing approach offers an opportunity for true concurrency on systems with multiple processors.
The Firefox web browser is currently implementing a version of the browser which incorporates multiple processes rather than having the entire application run in a single process. As discussed above, this entry provides some rationale behind why the development team decided to implement this functionality. Aside from the inherent performance gains offered by systems with multiple processors, there is increased stability. The stability is increased because independent processes decouple the entire browser architecture. This helps provide a degree of isolation not available in a single process. The stability gains are especially apparent when considering the multiple tabs used to view disparate web pages. Security could potentially be improved as a side effect of the isolation provided by processes. Finally, not mentioned in the entry but equally relevant in design terms, the distribution of responsibilities within the web browser system becomes very clear. It sometimes takes a drastic move to improve this design principle such as moving entire pieces of code to a separate process.
In this entry, a demonstration of the browser running a separate process for the tab content shows a clear stability improvement. Even after killing the content process, the user interface process remains in tact.
Showing posts with label processor. Show all posts
Showing posts with label processor. Show all posts
Thursday, July 9, 2009
Thursday, May 7, 2009
How Trac Determines The Wiki Processor
Within Trac is a powerful wiki syntax engine that offers a wide array of tools to the author who creates wiki pages. Richly formatted Trac wiki pages can be created in several ways. Just using the default wiki syntax to format plain text is often enough to get started. However, Trac offers much more. There are two other key components to the Trac wiki syntax; processors and macros. Macros invoke specific Python functionality, possibly with supplied parameters, to inject dynamic page content. Processors on the other hand, wrap around a specific chunk of wiki text and manipulate it in controlled ways. For instance, a plain processor would wrap some wiki text in three curly brackets. Doing this would simply transform the wrapped text to pre-formatted output. Wiki page authors can also invoke more exotic processors, such as html or syntax highlighting processors. To use a specific processor, the first line in the curly brackets must specify the processor name. The name of the processor must also be preceded by #!. So, for example, an html processor definition in Trac might look like {{{#!html hello world}}}. So, how does Trac know about these specific types of processors? Under the hood, The WikiProcessor class takes on this responsibility. The key task of this class is to load the required processor rendering functionality. Illustrated below is an elided view of the WikiProcessor class, showing only key attributes.
The logic executed by the WikiProcessor class to determine which processor is to be used in the rendering process takes place in the constructor, which accepts a processor name parameter. First, the constructor will check if the specified processor name is part of the builtin processor set. The builtin processor set in actually hard-coded in the constructor. If the specified processor name is found in this set, the processor attribute of the WikiProcessor instance becomes the method associated with the builtin processor name. If the specified processor isn't a builtin processor, the processor could potentially be a macro. All the macro providers, which contain actual macros, are retrieved from the WikiSystem class and iterated over. Each macro provider is then checked, to see if the specified processor is a macro. If it turns out that the specified processor is a macro, the macro_provider attribute of the WikiProcessor instance becomes the macro provider containing the matching macro. Also, the processor attribute of the WikiProcessor instance will become a method for rendering the macro. Finally, if the specified processor isn't a builtin and isn't a macro, the default rendering functionality is used.
This is an extremely flexible way to determine where the extensible wiki processing functionality resides. The one issue in the WikiProcessor constructor is that there are three if statements, all in the same context with no else. This means that all three if statements are executed no matter what. Not only is this inefficient, but the else adds a grouping aspect to the code. However, this is trivially easy to remedy.
The logic executed by the WikiProcessor class to determine which processor is to be used in the rendering process takes place in the constructor, which accepts a processor name parameter. First, the constructor will check if the specified processor name is part of the builtin processor set. The builtin processor set in actually hard-coded in the constructor. If the specified processor name is found in this set, the processor attribute of the WikiProcessor instance becomes the method associated with the builtin processor name. If the specified processor isn't a builtin processor, the processor could potentially be a macro. All the macro providers, which contain actual macros, are retrieved from the WikiSystem class and iterated over. Each macro provider is then checked, to see if the specified processor is a macro. If it turns out that the specified processor is a macro, the macro_provider attribute of the WikiProcessor instance becomes the macro provider containing the matching macro. Also, the processor attribute of the WikiProcessor instance will become a method for rendering the macro. Finally, if the specified processor isn't a builtin and isn't a macro, the default rendering functionality is used.
This is an extremely flexible way to determine where the extensible wiki processing functionality resides. The one issue in the WikiProcessor constructor is that there are three if statements, all in the same context with no else. This means that all three if statements are executed no matter what. Not only is this inefficient, but the else adds a grouping aspect to the code. However, this is trivially easy to remedy.
Subscribe to:
Posts
(
Atom
)