Another important principle underlying the E1 architecture is component model support. By following this principle, the replicated objects model has been extended to a component model. Such architecture makes E1 a convenient platform for the development of distributed applications.
Before proceeding to the discussion of the use of component models in distributed operating systems, we will briefly outline the concepts underlying the component software development paradigm.
Component-oriented approach to software development is based on the idea of constructing software systems from prefabricated reusable components. Components should be independently deployable, i.e. a component can be used by a third party, which was not engaged in design and implementation of the given component.
Software component is defined as a unit of composition with contractually specified interfaces and explicit context dependencies only . Components inherit essential concepts from object-oriented programming: encapsulation, polymorphism and availability through interfaces. However, components have additional properties not inherent to objects in object-oriented programming languages. Unlike objects, components are software products. In particular, it means that components can be developed and used independently by different sites. Component is an executable unit, rather than a programming language entity. Therefore, implementation inheritance is not supported for components. Component reuse is achieved by composition and aggregation. For two components to be interoperable, it is sufficient that they fit the requirements of a single component model, whether they were developed using the same or different programming languages. Components are characterized by higher degree of independence, than objects, and consequently, they have coarser granularity. As a rule, a component is constructed from several programming language objects.
The component model specifies the environment in which components operate, including: protected method invocation mechanism, naming service, late binding support, garbage collection service, component development tools, as well as a number of additional services, e.g. persistence, transactions, replication, object trading, etc. (see, for example, ).
Extending a component model across the network, yields a convenient environment for distributed applications development which, besides other advantages of component-oriented architecture, provides network transparency, i.e., the components, located in different nodes, can invoke each other the same way as in local interaction. This approach is implemented by middleware systems, e.g. COM , Corba , EJB .
It is remarkable that modern distributed operating systems often provide abstractions and services resembling distributed component models of middleware systems. Apparently, it can be explained by the fact that both classes of systems are intended to serve as software platforms for distributed computing. Like middleware systems, distributed operating systems generally provide unified access to distributed system resources by means of object-oriented interface. In some implementations, objects are first-class citizens (, , ) while other systems support more simple primitives, e.g. message ports in Mach  and Chorus  or portals in Opal  above which the notion of the object is introduced by the object-oriented application run-time. Distributed operating systems provide a number of services for maintaining distributed objects, which are quite similar to key component services. First of all, it is a protected interaction mechanism, supporting the uniform invocation of object methods from any network node, provided that the caller possesses sufficient capabilities. Besides that, distributed operating systems include global naming services that enable binding to an object by its unique identifier. Some systems also support persistence of objects [11, 10, 12, 49, 15].
Despite indicated similarities, today's distributed operating systems do not provide valid component models. In these systems object abstraction serves primarily as a convenient means of interprocess communication, rather than application structuring paradigm. Both operating system services and application software are structured as a set of server processes that expose entry points for communication with other programs. Through an entry point a server exports operations for access to a certain resource or a group of resources. These operations are invoked with object semantics. Client specifies the identifier of an entry point, plus the required operation code and a parameter set. In response to a call, a server can return one or more values. Thus an object serves mainly as a communication abstraction.
At the same time, component software development paradigm regards objects as independent software entities with private state, explicit context dependencies and contractually specified functionality. Such notion of components doesn't fit the framework of modern distributed operating systems. Implementing a component model on top of these systems would require an intermediate software layer, similar to traditional middleware.
We believe that implementation of a distributed component model at the operating system level has potential advantages over the middleware approach. The designer of a component-oriented middleware inevitably arrives at the implementation of some virtual machine over the operating system abstractions, which, naturally, results in significantly reduced performance. In order to get rid of this overhead, we suggest that component model support should be initially designed into operating system. Following this approach, E1 implements a distributed component model, based on the abstraction of replicated object.
On the low level, the E1 component model relies on the execution primitives, which are essentially different from the ones used by the conventional operating systems. The primary execution abstraction in the conventional systems is process or task, representing an instance of a program, loaded into memory. Each task runs in a separate address space. Within a task several execution threads can exist. This model does not appropriately support interacting objects of medium granularity .Therefore, we abandon it for the new execution model, tailored for component systems. In E1 all executable code and data belong to objects. All objects reside within a single 64-bit address space. E1 supports the migrating threads model , in which execution of a thread, invoking an object method, is transferred to the context of the invoked object. Migrating threads allow the departure from a server-style object design, where an object runs one or several threads to process incoming method invocations.
Another feature of E1 component model is that it is based on replicated objects. The ability to replicate is a generic property of all objects. E1 provides extensive support for replication, including flexible replica communication service and extensible library of replication strategies.
Besides these services, E1 component model provides:
- Protected interaction mechanism, supporting the transparent invocation of object methods from any network node. In E1 all invocations are processed by the local replica of an object. Legitimacy of each call is verified by the distributed Access Control Server (ACS).
- Class Repository and Dynamic Class Loader.
- Global Naming Service, providing mapping of a unique object identifier to one ore more contact points of a given object.
- Garbage collection system, which detects and destroys unused object replicas on the basis of reference graph analysis.
- Support for persistence, which provides object lifetime control, based on reliable storage of a consistent object state in nonvolatile memory.
- Component development tools, including E1 Interface Definition Language compiler and Replication Strategies Compiler.
Since both operating system services and application software are developed within the framework of a single E1 component model, the model has to be highly flexible, while introducing minimal overhead.