modified 2:50 PM 25 June 2004 Cover.fm
2nd REVIEW DRAFT
25 June 2004 (c) 2003 Kircher, Völter, Zdun
FOR REVIEW ONLY PLEASE DO NOT DISTRIBUTE THE PDF ANY FURTHER
modified 2:50 PM 25 June 2004 Cover.fm
Table of Contents
1 Series Foreword...... 5 2 Foreword ...... 7 3 Preface ...... 11 3.1 How to Read this Book ...... 11 3.2 Goals of the Book...... 13 3.3 About the Authors ...... 14 3.4 Acknowledgements ...... 16 3.5 Patterns and Pattern Languages...... 17 3.6 Our Pattern Form...... 22 3.7 Key to the Illustrations ...... 25 4 Introduction To Distributed Systems ...... 29 4.1 Distributed Systems: Reasons and Challenges...... 29 4.2 Communication Middleware...... 35 4.3 Remoting Styles ...... 37 5 Pattern Language Overview...... 49 5.1 Overview of the Pattern Chapters...... 57 6 Basic Remoting Patterns...... 65 6.1 Interactions among the Patterns...... 97 7 Identification Patterns...... 103 7.1 Interactions among the Patterns...... 115 8 Lifecycle Management Patterns...... 117 8.1 Basic Lifecycle Patterns ...... 118 8.2 General Resource Management Patterns...... 129 8.3 Interactions among the Patterns...... 142
modified 2:49 PM 25 June 2004 RemotingTOC.fm
9 Extension Patterns ...... 157 9.1 Interactions among the Patterns ...... 171 10 Extended Infrastructure Patterns ...... 175 10.1 Interactions among the Patterns ...... 193 11 Invocation Asynchrony Patterns ...... 197 11.1 Interactions among the Patterns ...... 216 11.2 Related Patterns: Invocation Asynchrony...... 229 12 Related Concepts, Technologies, and Patterns...... 231 12.1 Related Patterns ...... 232 12.2 Distribution Infrastructures...... 236 12.3 Quality Attributes...... 246 12.4 Aspect-Orientation and Remoting ...... 251 13 Technology Projections ...... 253 14 ...... NET Remoting Technology Projection255 14.1 Brief History of .NET Remoting ...... 255 14.2 .NET Concepts - A Brief Introduction...... 256 14.3 Pattern Map...... 258 14.4 An Simple .NET Remoting Example...... 259 14.5 Remoting Boundaries...... 264 14.6 Basic Internals...... 266 14.7 Error Handling ...... 267 14.8 Server-Activated Instances ...... 268 14.9 Client-Dependent Instances and Leasing...... 276 14.10 More Advanced Lifecycle Management...... 283 14.11 Internals of .NET Remoting...... 285
modified 2:49 PM 25 June 2004 RemotingTOC.fm
14.12 Extensibility of .NET Remoting...... 289 14.13 Asynchronous Communication ...... 296 14.14 Outlook to the Next Generation ...... 302 15 Web Services Technology Projection...... 305 15.1 Brief History of Web Services ...... 305 15.2 Pattern Map ...... 310 15.3 SOAP Messages ...... 310 15.4 Message Processing...... 320 15.5 Protocol Integration...... 328 15.6 Marshalling using SOAP XML Encoding...... 330 15.7 Lifecycle Management ...... 333 15.8 Client-Side Asynchrony ...... 335 15.9 Web Services and QoS ...... 340 15.10 Web Service Security ...... 342 15.11 Lookup of Web Services: UDDI ...... 343 15.12 Other Web Service Frameworks ...... 345 15.13 Consequences of the Pattern Variants Used in Web Services354 16 CORBA Technology Projection ...... 357 16.1 Brief History of CORBA...... 357 16.2 Pattern Map ...... 359 16.3 Initial Example ...... 360 16.4 CORBA Basics...... 362 16.5 Messaging...... 382 16.6 Real-Time CORBA ...... 387 17 Appendix ...... 395 17.1 Appendix A: Building Blocks for Component Infrastructures395 17.2 Appendix B: Extending AOP Frameworks for Remoting...399 modified 2:49 PM 25 June 2004 RemotingTOC.fm
18 References...... 407
modified 2:49 PM 25 June 2004 RemotingTOC.fm
Series Foreword
modified 2:49 PM 25 June 2004 ForewordFrankBuschmann.fm
modified 2:49 PM 25 June 2004 ForewordFrankBuschmann.fm
Foreword
Many of today’s enterprise computing systems are powered by distrib- uted object middleware. Such systems, which are common in industries such as telecommunications, finance, manufacturing, and government, often support applications that are critical to particular business operations. Because of this, distributed object middleware is often held to stringent performance, reliability, and availability requirements. Fortunately, modern approaches have no problem meeting or exceeding these requirements. Today, successful distrib- uted object systems are essentially taken for granted. There was a time, however, when making such claims about the possi- bilities of distributed objects would have met with disbelief and derision. In their early days, distributed object approaches were often viewed as mere academic fluff with no practical utility. Fortunately, the creators of visionary distributed object systems such as Eden, Argus, Emerald, COMANDOS, and others were undeterred by such opinion. Despite the fact that the experimental distributed object systems of the 1980s were generally impractical — too big, too slow, or based on features available only from particular specialized platforms or programming languages — the exploration and experimentation required to put them together collectively paved the way for the prac- tical distributed objects systems that followed. The 1990s saw the rise of several commercially successful and popular distributed object approaches, notably the Common Object Request Broker Architecture (CORBA) promoted by the Object Management Group (OMG) and Microsoft’s Common Object Model (COM). CORBA was specifically designed to address the inherent heterogeneity of busi- ness computing networks, where mixtures of machine types, operating systems, programming languages, and application styles are the norm and must coexist and cooperate. COM, on the other hand, was built specifically to support component-oriented applications running on the Microsoft Windows operating system. Today, COM has been modified 2:49 PM 25 June 2004 ForewordSteveVinoski.fm
largely subsumed by its successor, .NET, while CORBA remains in wide use as a well-proven architecture for building and deploying significant enterprise-scale heterogeneous systems, as well as real-time and embedded systems. As this book so lucidly explains, despite the fact that CORBA and COM were designed for fundamentally different purposes, they share a number of similarities. These similarities range from basic notions, including remote objects, client and server applications, proxies, marshallers, synchronous and asynchronous communications, and interface descriptions, to more advanced areas, including object identi- fication and lookup, infrastructure extension, and lifecycle management. Not surprisingly, though, these similarities do not end at CORBA and COM. They can also be found in newer technologies and approaches, including .NET, the Java 2 Enterprise Edition (J2EE), and even in Web Services (which, strictly speaking, is not a pure distributed objects technology, but still has inherited many of its characteristics). Such similarities are of course better known as patterns. Patterns are generally not so much created as they are discovered, much like a miner finds a diamond or a gold nugget buried in the earth. Successful patterns result from the study of successful systems, and the remoting patterns presented here are no exception. Our authors, Markus, Michael, and Uwe, who are each well versed in both the theory and practice of distributed objects, have worked extensively with each of the technologies I’ve mentioned. Applying their pattern mining talents and efforts, they have captured for the rest of us the critical essence of a number of successful solutions and approaches found in a number of similar distributed objects technologies. Given my own long history with CORBA, I am not surprised to find that several of the patterns that Markus, Michael, and Uwe document here are among my personal favorites. For example, topping my list is the Invocation Interceptor pattern, which I have found to be critical for creating distributed objects middleware that provides extensibility and modularity without sacrificing performance. Another favorite of mine is the Leasing pattern, which can be extremely effective for managing object lifecycles. This book does not simply describe a few remoting patterns, however. While many patterns books comprise only a loose collection of modified 2:49 PM 25 June 2004 ForewordSteveVinoski.fm
patterns, this book also provides a series of technology projections that tie the patterns directly back to the technologies that employ them. These projections clearly show how the patterns are used within .NET, CORBA, and Web Services, effectively recreating these architectures from the patterns mined from within them. With technology projec- tions like these, it has never been easier to see the relationships and roles of different patterns with respect to each other within an entire architecture. These technology projections clearly link the patterns, which are already invaluable by themselves, together into a compre- hensive, harmonious, and rich distributed objects pattern language. In doing so, they conspicuously reveal the similarities among these different distributed object technologies. Indeed, we might have avoided the overzealous and tiresome “CORBA vs. COM” arguments of the mid-1990s had we had these technology projections and patterns at the time. Distributed objects technologies continue to evolve and grow. These patterns have essentially provided the building blocks for the experi- mental systems of the 1980s, for the continued commercial success and wide deployment of distributed objects that began in the 1990s, and for today’s Web Services integration approaches. Due to the never-ending march of technology, you can be sure that before too long, new technol- ogies will come along to displace Web Services. You can also be sure that the remoting patterns that Markus, Michael, and Uwe have so expertly provide for us here will be at the heart of those new technolo- gies as well. Steve Vinoski Chief Engineer IONA Technologies March 2004
modified 2:49 PM 25 June 2004 ForewordSteveVinoski.fm
modified 2:49 PM 25 June 2004 ForewordSteveVinoski.fm
Preface
Today distributed object middleware belongs to the basic elements in the toolbox of software developers, designers, and architects devel- oping distributed systems. Popular examples of such distributed object middleware systems are CORBA, Web Services, DCOM, Java RMI, and .NET Remoting. There are many other books that explain how a partic- ular distributed object middleware works. If you just want to use one particular distributed object middleware, many of these books are highly valuable. However, as a professional software developer, designer, or architect working with distributed systems, you will also experience situations in which just understanding how to use one particular middleware is not enough. To do this, you are required to gain a deeper understanding of the inner workings of the middleware in order to customize or extend the middleware to your needs. Or, as a consequence of business requirements, you are forced to migrate your system to a new kind of middleware. Or, you need to integrate two systems which use two different middleware products. This book is intended to help you in these and similar situations: it explains the inner workings of successful approaches and technologies in the field of distributed object middleware in a practical manner. To achieve this we use a pattern language describing the essential building blocks of distributed object middleware based on a number of compact, Alexandrian-style [AIS+77] patterns. We supplement the pattern language with three technology projections that explain how the patterns are realized in different real world examples of distributed object middleware systems: .NET Remoting, Web Services, and CORBA.
How to Read this Book This book primarily aims at software developers, designers, and archi- tects having a at least basic understanding of software development and design concepts. modified 2:49 PM 25 June 2004 Preface.fm
For readers who are new to patterns, we introduce patterns and pattern languages to some extend in this chapter. Readers familiar with patterns might want to skip that section. We also briefly explain the pattern form and the diagrams used in this book at the end of this chapter. Readers might at least want to scan this information and use it as a reference, when reading the later chapters of the book. In the pattern chapters and the later technology projections we assume some knowledge of distributed system development. We give a short introduction to the basic terminology and concepts used in this book in the next chapter. Readers who are not familiar with the field or who want to refresh their knowledge should read this chapter. Readers who are experts in the field might want to skip the Introduction to Distributed Systems chapter. If you are completely new to this field, you might want to read a more detailed introduction like Tanenbaum and van Steen’s Distributed Systems: Principles and Paradigms [TS02]. For all readers, we recommend reading the pattern language chapters as a whole. This should give you a fairly good picture of how distrib- uted object middleware systems work. When working with the pattern language, you usually can directly go to particular patterns of interest and use the pattern relationships described in the pattern descriptions to find related patterns. Details on the interactions among the patterns can be found at the end of each pattern chapter depicted in a number of sequence diagrams. We have not included these interactions in the individual pattern descrip- tions for two reasons: Firstly, it would make the pattern chapters less readable as a whole. Secondly, the patterns in each chapter have strong interactions - so it makes sense to illustrate them with integrated exam- ples instead of scattering the examples across the individual pattern descriptions. Especially, if you want to implement your own distributed object middleware system or extend an existing one, we recommend to look closely at the sequence diagram examples. This will give you some more insight into how the pattern language can be implemented. As a next step, you may want to read the technology projections to see a couple of well established real-world examples of how the pattern language got implemented by vendors.
modified 2:49 PM 25 June 2004 Preface.fm
If you want to understand the commonalities and differences between some of the mainstream distributed object middleware systems, you should read the technology projections in any order you like. They are completely independent of each other.
Goals of the Book Numerous projects use, extend, integrate, customize, and build distrib- uted object middleware. The major goal of the pattern language in this book is to provide knowledge about the general, recurring architecture of successful distributed object middleware as well as more concrete design and implementation strategies. As a reader you might benefit from reading and understanding this pattern language in several ways: • If you want to use a distributed object middleware, you will benefit from better understanding the concepts of your middleware implementation and this, in turn, helps you to make better use of the middleware. If you know how to use one middleware system and need to switch to another, then understanding the patterns of distributed object middleware helps you to see the commonalities in spite of different remoting abstractions, terminologies, imple- mentation language concepts, and so forth. • Sometimes you need to extend the middleware with additional functionality. For instance, consider you are developing a Web Service application. Because Web Services are relatively new, your chosen Web Service framework might not implement certain secu- rity or transaction features that you really need for your application. Then you need to implement these features on your own. Here, the patterns help you to find the best hooks for extending the Web Service framework. The patterns show you the alternatives of successful implementations of such extensions. The book also let you find similar solutions in other middleware imple- mentations so that you can get some ideas - to avoid reinventing the wheel. Another typical extension is the introduction of “new” remoting styles, implemented on top of existing middleware. Consider server-side component architectures, such as CORBA Components, COM+, or Enterprise Java Beans (EJB): they use distributed object middleware implementations as a foundation for remote communication [VSW02]. They extend the middleware modified 2:49 PM 25 June 2004 Preface.fm
with new concepts. Again, as a developer of a component architec- ture, you have to understand the patterns of the distributed object middleware, for instance, to integrate the lifecycle models of the components and remote objects. • While distributed object middleware is used to integrate heteroge- neous systems, you might encounter situations in which you need to integrate the various middleware systems. Just consider the situ- ation where your employer buys another company, which uses a different middleware product from the one used in your company. So you need to integrate the two middleware solutions in order to let the information systems of the two companies play in concert. Here, the patterns help you find integration spots and identify promising solutions. • In some, more rare cases you need to customize a distributed object middleware, or even build it from scratch. Consider for instance an embedded system with tight constraints regarding memory consumption, performance, and real-time communication [Aut04]. If no suitable middleware product exists or all available products turn out to be inappropriate and/or have a footprint that is to large, the developers must develop their own solution. As an alter- native, you might take a look at existing open-source solutions and try to customize them for your needs. Here the patterns help you to identify critical components of the middleware and assess the effort for customizing them. If customizing an existing middle- ware does not seem to be feasible, you can use the patterns to build a new distributed object middleware for your application. The list above are just a few motivating examples. We hope these exam- ples illustrate the broad variety of situations in which you might want to get a deeper understanding of distributed object middleware. And, as these situations are occurring over and over again, we hope these examples illustrate why we - as the authors of this book - think that the time is ready for a book that explains these issues in a way accessible for practitioners.
About the Authors
Markus Völter modified 2:49 PM 25 June 2004 Preface.fm
Markus works as an independent consultant on software technology and engineering out of Heidenheim, Germany. His primary focus is on software architecture and patterns, middleware and model-driven software development. Markus has consulted and coached in many different domains such as banking, health care, e-business, telematics, astronomy and automotive embedded systems, in projects ranging from 5 to 150 developers. Markus is also a regular speaker at international conferences on soft- ware technology and object orientation. Among others, he has given talks and tutorials at ECOOP, OOPSLA, OOP, OT, JAOO and GPCE. Markus has published patterns at various *PLoP conferences and is constantly writing articles in various magazines on topics he is inter- ested in. He is also co-author of the book Server Component Patterns (also Wiley Pattern Series). When not dealing with software, Markus enjoys cross-country flying in the skies over southern Germany in his sailplane. Markus can be reached at [email protected] or via www.voelter.de
Michael Kircher Michael Kircher is currently working as Senior Software Engineer at Siemens AG Corporate Technology in Munich, Germany. His main fields of interest include distributed object computing, software archi- tecture, patterns, agile methodologies, and management of knowledge workers in innovative environments. He has been involved as a consultant and developer in many projects, within various Siemens business areas, building software for distributed systems. Among those were the development of software for UMTS base stations, toll systems, postal automation systems, and operation and maintenance software for industry and telecommunication systems. In recent years he has published at numerous conferences on topics such as patterns, software architecture for distributed systems, and eXtreme Programming and organized several workshops at confer- ences such as OOPSLA and EuroPLoP. In his spare time Michael likes to combine family life with enjoying nature, doing sports or just watching wildlife.
modified 2:49 PM 25 June 2004 Preface.fm
Michael can be reached at [email protected] or via www.kircher-schwanninger.de
Uwe Zdun Uwe Zdun is currently working as an assistant professor in the depart- ment of information system at the Vienna University of Economics and Business Administration. He received his doctoral degree from the University of Essen in 2002, where he has also worked as research assis- tant from 1999 to 2002 in the software specification group. His research interests include software patterns, scripting, object-orientation, soft- ware architecture, and web engineering. Uwe has been involved as a consultant and developer in many software projects. He is author of a number of open-source software systems, including Extended Object Tcl (XOTcl), ActiWeb, Frag, and Leela, as well as many other open- source and industrial software systems. In recent years he has published in numerous conferences and journals, and co-organized a number of workshops at conferences such as EuroPLoP, CHI, and OOPSLA. He enjoys the outdoor sports of hiking, biking, and running, and the indoor sports of pool, guitar playing, and sports watching. Uwe can be reached at [email protected] or via http://wi.wu-wien.ac.at/ ~uzdun
Acknowledgements A book like the one you have in your hands would not have been possible if not many other people would have supported us. For their support in discussing the contents of the book and for providing their feedback we express our gratitude. First of all, we want to thank our shepherd, Steve Vinoski, and the pattern series editor, Frank Buschmann. They have read the book several times and provided in-depth comments on technical content as well as on the structure and coherence of the pattern language. We also want to thank the following people who have provided comments on various versions of the manuscript as well as on extracted papers that have been workshopped at VikingPLoP 2002 and modified 2:49 PM 25 June 2004 Preface.fm
EuroPLoP 2003: Mikio Aoyama, Steve Berczuk, Valter Cazzalo, Anniruddha Gokhale, Lars Grunske, Klaus Jank, Kevlin Henney, Wolf- gang Herzner, Don Hinton, Klaus Marquardt, Jan Mendling, Roy Oberhauser, Joe Oberleitner, Juha Pärsinen, Michael Pont, Alexander Schmid, Kristijan Elof Sorenson (thanks for playing shepherd and proxy), Mark Strembeck, Oliver Vogel, Johnny Willemsen, and Eber- hard Wolff. Finally, we thank those that have been involved with the production of the book: our copy-editor Steve Rickaby and editor Gaynor Redvers- Mutton. It is a pleasure working with such proficient people.
Patterns and Pattern Languages Over the past couple of years, patterns have become part of the main- stream of software development. They appear in different kinds and forms. The most popular patterns are those for software design, pioneered by the Gang-of-Four (GoF) book [GHJV95] and continued by many other pattern authors. Design patterns can be applied very broadly, because they focus on everyday design problems. In addition to design patterns, the patterns community has created patterns for software architecture [BMR+96, SSRB00], analysis [Fow96] and even non-IT topics such as organizational or pedagogical patterns [Ped04, FV00]. There are many other kinds of patterns, some are specific for a partic- ular domain.
What is a Pattern? A pattern, according to the original definition of Alexander1 [AIS+77], is: …a three-part rule, which expresses a relation between a certain context, a problem, and a solution.
1. In his book, A Pattern Language – Towns • Buildings • Construction [AIS+77] Christopher Alexander presents a pattern language of 253 patterns about archi- tecture. He describes patterns that guide the creation of space for people to live, including cities, houses, rooms and so forth. The notion of patterns in software builds on this early work by Alexander. modified 2:49 PM 25 June 2004 Preface.fm
This is a very general definition of a pattern. It is probably a bad idea to cite Alexander in this way, because he explains this definition exten- sively. In particular, how can we distinguish a pattern from a simple recipe? Take a look at the following example:
Context You are driving a car.
Problem The traffic lights in front of you are red. You must not run over them. What should you do?
Solution Brake.
Is this a pattern? Certainly not. It is just a simple, plain if-then rule. So, again, what is a pattern? Jim Coplien, on the Hillside web-site [Cop04], proposes another, slightly longer definition which summarizes the discussion in Alexander’s book: Each pattern is a three-part rule, which expresses a relation between a certain context, a certain system of forces which occurs repeatedly in that context, and a certain software configuration which allows these forces to resolve themselves. Coplien mentions forces. Forces are considerations that somehow constrain or influence the solution proposed by the pattern. The set of forces builds up tension, usually formulated concisely as a problem statement. A solution for the given problem has to balance the forces somehow, because usually the forces cannot all be resolved optimally – a compromise has to be found. The pattern, in order to be understandable by the reader, should describe how the forces are balanced in the proposed solution, and why they have been balanced in the proposed way. In addition, the advan- tages and disadvantages of such a solution should be explained, to allow the reader to understand the consequences of using the pattern.
Patterns are solutions to recurring problems. They therefore need to be quite general so that they can be applied to several concrete problems. However, the solution should be concrete enough to be practically useful, and it should include a description of a specific software config- uration. Such a configuration consists of the participants of the pattern, modified 2:49 PM 25 June 2004 Preface.fm
their responsibilities, and their interactions. The level of detail of this description can vary, but after reading the pattern, the reader should know what he has to do to implement the pattern’s solution. As the above discussion highlights, a pattern is not merely a set of UML diagrams or some code fragments. Patterns are never “new ideas”. Patterns are proven solutions to recur- ring problems. So known uses for a pattern must always exist. A good rule of thumb is that something that has not at least three known uses is hardly a pattern. In software patterns, this means that systems must exist that are implemented according to the pattern. The usual approach to writing patterns is not to invent them from scratch – instead they are discovered in, and then extracted from, real-life systems. These systems then serve as known uses for the pattern. To find patterns in software systems, the pattern author has to abstract the problem/solution pair from the concrete instances found in the systems at hand. Abstracting the pattern while preserving comprehen- sibility and practicality is the major challenge of pattern writing. There is another aspect of what makes a good pattern, the quality without a name (QWAN) [AIS+77]. The quality without a name cannot easily be described, the best approximation is universally-recognizable aesthetic beauty and order. So, a pattern’s solution must somehow appeal to the aesthetic sense of the pattern reader – in our case, to the software developer, designer, or architect. While there is no universal definition of beauty, there certainly are some guidelines as to what is a good solu- tion and what is not. For example, a software system should be efficient, flexible and easily understandable while addressing a complex problem, and so on. The principle of beauty is an important - and often underestimated - guide for judging whether a technological design is good or bad. David Gelernter details this in his book Machine Beauty [Gel99].
Classifications of Patterns in this Book The patterns in this book are software patterns. They can further be seen as architectural patterns or design patterns. It is not easy to draw the line between architecture and design, and often the distinction is depended on the situation you are in and the viewpoint that you take. For a rough
modified 2:49 PM 25 June 2004 Preface.fm
distinction, let’s refer to the definition of software architecture from Bass, Clements, and Kazman [BCK98]: The software architecture of a program or computing system is the struc- ture or structures of the system, which comprise software components, the externally-visible properties of those components and the relation- ships among them. What we can see here, is that it heavily depends on the viewpoint of the designer or architect whether a specific pattern is categorized as an architectural pattern or a design pattern. Consider for instance the Interpreter pattern [GHJV95]. The description in the Gang-of-Four book describes it as a concrete design guideline. Yet, according to the above software architecture definition, instances of the pattern are often seen as a central elements in the architecture of software systems because an Interpreter is a central component of the system that is externally visible. Most of the patterns in this book can be seen as falling into both catego- ries - design patterns and architectural patterns. From the viewpoint of the designer they provide concrete guidelines for the design of a part of the distributed object middleware. Yet, they also comprise larger, visible structures of the distributed object middleware and focus on the most important components and their relationships. Thus, according to the above definition they are architectural foundations of the distrib- uted object middleware as well.
From Patterns to Pattern Languages A single pattern describes one solution to a particular, recurring problem. However, ‘real big problems’ usually cannot be described in one pattern without compromising readability. The pattern community has therefore come up with several ways to combine patterns to solve a more complex problem or a set of related problems: • Compound patterns are patterns that are assembled from other, smaller patterns. These smaller patterns are usually already well known in the community. Often, for a number of related smaller patterns, known uses exist in which these patterns are always used together in the same software configuration. Such situations are good candidates for being described as a compound pattern. It is modified 2:49 PM 25 June 2004 Preface.fm
essential that the compound pattern actually solves a distinct problem, and not just a combination of the problems of its contained patterns. A compound pattern also resolves its own set of forces. An example for a compound pattern is Bureaucracy by Dirk Riehle [Rie98] that combines Composite, Mediator, Chain of Responsibility, and Observer (all from the GoF book). •A family of patterns is a collection of patterns that solves the same general problem. Each pattern either defines the problem more specifically, or resolves the common forces in a different way. For example, different solutions could focus on flexibility, perfor- mance or simplicity. Usually each of the patterns also has different consequences. A family therefore describes a problem and several proven solutions. The reader has to select the appropriate solution, taking into account how he wants to resolve the common forces in his particular context. A good example is James Noble’s Basic Rela- tionship Patterns [Nob97], that describe several alternatives of how logical relationships among objects can be realized in software. •A collection, or system of patterns comprises several patterns from the same domain or problem area. Each pattern stands on its own, sometimes referring to other patterns in the collection in its imple- mentation. The patterns form a system because they can be used by a developer working in a specific domain, each pattern resolving a distinct problem the developer might come across during his work. A good example is Pattern Oriented Software Architecture by Buschmann, Meunier, Rohnert, Sommerlad, and Stal (also known as POSA 1 – see [BMR+96]). The most powerful form of combining patterns is a pattern language. There are several characteristics of pattern languages: • A pattern language has a language-wide goal. The purpose of the language is to guide the user step by step to reach this goal. The patterns in a pattern language are not necessarily useful in isola- tion. The patterns in this book form a pattern language in the domain of distributed object middleware. • A pattern language is generative in nature. Applying the pattern language generates a whole. This generated whole should be ‘beautiful’ in the sense of QWAN. The whole is “generated” by modified 2:49 PM 25 June 2004 Preface.fm
applying the patterns in the pattern language one after another in an incremental process of refinement. The basic idea is that - with each refinement step - the whole gets more and more coherent. • To generate the whole, the pattern language has to be applied in a specific order. This order is defined by one or more sequences. Depending on the context where the pattern language is applied or which aspects of the whole are actually required, there can be several sequences through a pattern language. • Because the patterns must be applied in a specific sequence, each pattern must define its place in this sequence. To achieve this, each pattern has a section called its context, which mentions earlier patterns that have to be implemented before the current pattern can be implemented successfully. Each pattern can also feature a resulting context that describes how to continue. It contains refer- ences to the patterns that can be used to help in the implementation of the current pattern or explain how to proceed in the incremental refinement process of the whole. Pattern languages—in contrast to the other forms of combining patterns discussed above—do not only specify solution to specific problems, but also describe a way to create the whole, the overall goal of the pattern language. Note that one particular pattern can play a role in different pattern languages. For instance, we integrate some patterns from other source in our pattern language, such as the Broker pattern [BMR+96] which we use to motivate the overall problem and context of the pattern language in this book.
Our Pattern Form In this section, we provide a brief introduction to the pattern form used in this book. The form of our patterns is similar to the Alexandrian [AIS+77] format, but omits examples in the pattern description and photographs visualizing the pattern. This book does contain many examples of the patterns; but instead of presenting an example for each individual pattern, the examples appear separate in form of UML sequence diagrams, at the end of each pattern chapter, and as Tech- nology Projections.
modified 2:49 PM 25 June 2004 Preface.fm
The individual pattern descriptions are structured as follows: Each pattern starts with a name. The name is an important part of a pattern in a pattern language because it is used throughout the language to refer to the particular pattern. When referencing pattern names from our pattern language, we always write them in SMALLCAPS font. External patterns from the literature are highlighted in Italics. The next section is the context of the pattern in the pattern language. The context is separated by three stars from the main body of the pattern. The main body starts with a problem section written in bold face font. The problem, addressed by the pattern, is then illustrated in more detail in plain font. Especially the system of forces leading to the pattern’s solution is discussed here. The section is written in two different styles: • In structural patterns this section contains problem details and a short discussion of forces. • In behavioral patterns, found in the Lifecycle Patterns and Client Asynchrony Patterns chapters, this section contains an example application scenario that motivates the need for the pattern’s solu- tion. We feel that such an example illustrates the forces much better for those patterns than an abstract discussion. Following the problem discussion, the solution of the pattern is again provided using bold face. It is illustrated by a figure. Three stars sepa- rate the main body of the pattern from the solution details that follow. The solution details discuss variants of the pattern, related patterns (in the pattern language and from literature), as well as the consequences of applying the pattern. Examples and known uses are provided in the Technology Projections chapter, which projects the patterns on a certain technology. We present technology projections for .Net Remoting, Web Services, and CORBA. Other known uses of the patterns are discussed in the Chapter Related Concepts, Technologies, and Patterns. Below, the pattern format
modified 2:49 PM 25 June 2004 Preface.fm
layout is illustrated by an example with some side-headings for explanation.
Structure of the Pattern Chapters The pattern chapters have a specific structure that we want to outline quickly. Some of the chapters provide additional sections, but the following three sections are common to each chapter: modified 2:49 PM 25 June 2004 Preface.fm
• Each chapter starts with an introduction of the general topic of the chapter. Each pattern in the chapter is introduced with one or two sentences. An overview diagram that shows the relationship between the different patterns is provided. This diagram also connects the patterns to patterns in other chapters - the patterns from other chapters are rendered in grey in these figures. • The second part of each pattern chapter then introduces the patterns themselves. Each pattern - using the structure shown above - covers a couple of pages. • A third section called Interactions among the Patterns shows how the patterns interact. This is done mainly using UML sequence diagrams, illustrating certain example usage scenarios. Additional information on how the patterns collaborate are provided in the text. Note that these diagrams are just scenarios that might omit certain parts or show certain details in a different way than other possible scenarios. They only show a relevant aspect that should be highlighted by the particular example, and abstract from other parts of the solution. Otherwise, the diagrams would become way too complex. The Technology Projection chapters provide more detailed examples focussing on the pattern language as a whole.
Key to the Illustrations Most of the illustrations in this book use the UML with some slight variations; we explain the UML subset we use in the following sections. Only the collaboration diagrams used in the pattern descriptions cannot really be called UML.
Collaborations Each pattern is illustrated with a “collaboration diagram”. In addition to the dynamic collaboration semantics as known from the respective UML diagrams, we also display containment structures in these diagrams. Thus they are not formally UML diagrams. Anyway, we
modified 2:49 PM 25 June 2004 Preface.fm
hope they are useful. The following figure provides an example illus- tration, annotated with comments to serve as a key.
Value Type Sequence number, name Application and parameters Thread of the invoked "Real" Return value Process method method Remote Object invocation
Process A Process B Holder 2) serialize() Remote Holder Object
Proxy Machine Boundary
3a) create() anObject 3b) <
Some more detail on the notation: • Although remoting is typically used to communicate from one machine to another, that’s not necessarily so. It can also be used just to communication between two processes on the same machine. This is the reason, why the Machine Boundary is optional. •An apparent method invocation means that the denoted operation is logically executed directly by the invoking entity, but in reality, there might be other intermediate steps involved (such as a proxy). •The <
mentioned in the attached box – are executed directly after one another.
Class diagrams Class diagrams are standard UML, except for the dependency arrow, which we draw as a solid arrow instead of a lined arrow. This is purely for aesthetic reasons.
Class
Inheritance: Dependency: PricingFactory is a Client depends <
<
Interface
Pricing creates instances of PricingFactory
Implementation: Dependency with class Pricing Client explanation: implements the PricingFactory interface IPricing creates instances of Pricing
Interactions At the end of each pattern chapter we illustrate the patterns, their use, and their collaborations with a set of sequence diagrams. These are mostly standard UML and thus require no specific explanation. However, we use some non-standard but intuitive notations, which the following example illustrates. For example, a multi-threaded object has
modified 2:49 PM 25 June 2004 Preface.fm
two lifelines; and we use a stereotype <
an new thread is an named anonymous created; i.e. the object is object object an invocation requester now created (named i) has two threads
Client Client Client Requester i:Invocation Request Proxy Handler
someOp() invokeOneway(targetObject, "someMethod", {x}) object <
<
object does method is thread something for called, terminates which no return value specific method is stored in is available variable object ceases to exist
modified 2:49 PM 25 June 2004 Preface.fm
Introduction To Distributed Systems
In this chapter we briefly introduce distributed systems. In particular, we motivate the basic challenges addressed by the patterns in this book and introduce important terminologies and concepts. This chapter, however, cannot provide a complete introduction to the broad field of distributed systems. More extensive introductions to these topics can be found in other books such as Tanenbaum and van Steen’s Distributed Systems: Principles and Paradigms [TS02].
Distributed Systems: Reasons and Challenges This section provides an introduction to distributed systems, the reason s why they exist, and the challenges in their design.
Application Areas for Distributed Systems The application areas for distributed systems are diverse and broad. Many major large and complex systems in use today are distributed systems. In the following we will give a few examples to better illus- trate this. The Internet can be seen as a large distributed system with a huge number of servers providing services via a set of communication proto- cols, such as HTTP, FTP, Telnet, and SMTP, to an even larger number of clients. The protocols used in the Internet are simple, rugged, and proven. Telecommunication networks use digital switches that run software to provide the communication facilities. That is, telecommunications networks heavily depend on distributed communication. As the devel- opment cycles are getting shorter in this domain, the use of low-level programming and communication means is replaced by object- oriented programming languages and corresponding distributed object middleware technologies. Those allow for higher programming
modified 2:49 PM 25 June 2004 Introduction.fm
efficiency, though often at the cost of memory overhead and somewhat reduced execution performance. Business-to-business (B2B) collaboration systems, conducting electronic commerce among businesses, are also an important application area for distributed systems. Today Electronic Data Interchange (EDI) [Ans04] is heavily used for electronic commerce, but web-based technologies such as XML-based Web Services will be most probably used in the future in this area (see for instance BEPL4WS [ACD+03]). International financial transactions are executed via a distributed system provided by SWIFT (Society of Worldwide Interbank Financial Tele- communication). SWIFT is an industry-owned cooperation supplying secure, standardized messaging services and interface software to financial institutions. In 2002 there have been more than 7,500 financial institutions in 200 countries connected to SWIFT processing about 7 million messages daily [Swi02]. The system was originally established to simplify the execution of international payments. Today there have been several financial and infrastructure services added to the portfolio. Embedded systems, such as in-vehicle software, elevator control systems, household appliances, mobile devices, and many others, have crucial requirements for distributed communication. For example, modern passenger cars contain a complex network of so-called electronic control units (ECU). These ECUs run software that controls a particular aspect of the car. The features of a car are typically interrelated: for example, you should not be able to switch critical ECUs into diagnostic mode while the car is driving. Thus the ECUs need to communicate with each other. In this example - similar to other embedded systems - strict timing requirements have to be obeyed. More and more embedded systems become network-aware, using for example wireless technologies, and therefore requiring efficient programmability of distributed communication. The upcoming AUTOSAR middleware standard [Aut04] addresses these concerns in the context of in-vehicle software. Many scientific applications, such as DNS analysis, extraterrestrial signal interpretation, or cancer research, need massive amounts of computa- tional power and thus cannot easily be run on a single machine.
modified 2:49 PM 25 June 2004 Introduction.fm
Clusters, GRIDs, or distributed peer-to-peer systems are commonly used to collaboratively solve these kinds of problems. These were only a few examples of distributed systems. Many other fields use distributed systems as well. We hope this short and incom- plete list of examples gives you as a reader an impression of the diversity and complexity of distributed systems.
Reasons for Using Distributed Systems Why do we use distributed systems? There are many reasons why distributed systems are used today. In general, we can distinguish problem-related reason and property-related reasons, often occurring together. Problem-related reasons for distributed systems occur when we face problems that are inherently distributed. For instance, if an user in Europe wants to read a Web page that is located on a server in the US, then the Web page has to be transported to the remote user – there is no way around that, it is simply the purpose of the system. There are also property-related reasons for using distributed systems - that is, reasons that are motivated by a particular system property that should be improved by distributing the system. Examples of such system properties are: • Performance and Scalability: If a system has to cope with such heavy loads that a single machine cannot cost-effectively solve the problem, the problem is divided and assigned to several machines, now sharing the load. To allow them to efficiently handle the load, the machines have to be coordinated in some way (this process is called “load balancing”), resulting in a distributed system. For example, most Web sites with very high hit rates are served by more than one machine. Another example is the area of super- computing: GRIDs of smaller machines are assembled to provide a performance unattainable by any single machine. We discuss availability and scalability patterns in Chapter Related Concepts, Technologies, and Patterns. • Fault Tolerance: Another reason for using distributed systems is fault tolerance. All hardware devices have some Mean Time Between Failure (MTBF), which in reality is smaller than infinity. modified 2:49 PM 25 June 2004 Introduction.fm
Software can also fail: a program might have a bug or some non- deterministic behavior that results in a failure or in “strange behavior” that may happen only occasionally. As a consequence, every machine, or a part of it, will fail at some time. If the overall system should continue working in such cases, it must be made sure that the system does not fail completely when a partial fault occurs. One approach to do this is to distribute the software system over many machines, and make sure clients do not notice when one of the serving machines fails. Again, coordination among different software components running on these machines results in a distributed system. Note that there are also other ways for providing fault tolerance than hardware redundancy. For more details, refer to the Chapter Related Concepts, Technologies, and Patterns. • Service and Client Location Independence: In many systems the loca- tion of clients and services are not known in advance. In contrast to classical mainframe or client/server systems, services can be trans- parently executed on remote hosts, for instance, equipped with more storage or computing power. For example, in a peer-to-peer system, new - distributed or local - peers, providing additional services, might join and leave the system from time to time. • Maintainability and Deployment: Deployment of software to a large number of machines is a maintenance nightmare increasing the Total Cost of Ownership (TCO) of a system. An alternative solu- tion is to provide thin clients that only accept user inputs and present outputs. The business logic is remotely located on central servers. Changes to the business logic do not affect clients. Enter- prise systems use this thin client approach, keeping the “actual functionality” and the data on one or more central machines. • Security: Another reason for using a distributed system is security. Security information, such as user credentials, might be consis- tently kept at a central site and accessed from many remote places. On the other hand, for security reasons, some information or func- tionality might not be kept at a single site only, but instead distributed over a number of nodes, perhaps administered by different people and organizations. Also, some machines that store critical data might be located in specially secured computing centers: for example, a restricted area that requires a special key modified 2:49 PM 25 June 2004 Introduction.fm
for access and is monitored with security cameras. Often, these secured machines need to be accessed by other nodes of the system. Again, to coordinate the nodes, remote communication is necessary. • Business Integration: In the past, business was mainly performed by persons that interacted with each other, either directly, per mail, or per phone. When e-mail started to appear, some business was done via mails, but still orders were typed in by persons, sitting at their personal computer. In the last years, the term “Enterprise Application Integration” (EAI) appeared. EAI is about integrating the different systems in an enterprises into one coherent, collabo- rating „system of systems“. This integration involves communication among the various systems using different remoting styles as well as data mapping and conversions.
Challenges in Distributed Systems Compared to traditional, non-distributed systems there are additional challenges to be taken into account when engineering distributed systems. Important challenges are: • Network Latency: A remote invocation in a distributed system takes considerably more time than an invocation in a non-distributed system. In case a certain performance level is required from the distributed system or when strict deadlines have to be obeyed, this additional time delay has to be taken into account. • Predictability: The time that it takes to invoke an operation differs from invocation to invocation because it depends on the network load and other parameters, such as the actual location of the remote process, how fast the invocation travels across the network and is processed by the remote process. The network can even fail. Lacking end-to-end predictability of remote invocations is espe- cially problematic for systems with hard real-time requirements which demand that specified deadlines must not be missed – otherwise it constitutes a system failure. Guaranteeing real-time requirements in distributed systems is a major challenge in many distributed, real-time embedded systems, such as aircraft flight control. Note that predictability cannot be assumed in non-distrib- uted systems either. An operation invocation time is influenced by modified 2:49 PM 25 June 2004 Introduction.fm
many factors, such as processor load or the status of a garbage collector. However, for many systems, these times can be assumed to be very small and constant - and thus can be neglected in prac- tice. Such assumptions cannot be made in a distributed system. Predictable transmission times in distributed systems can be provided only by using time-triggered communication [Kop97], which is increasingly used in safety-critical real-time applications. • Concurrency: Other problems arise from the fact that there is real concurrency in a distributed system. In contrast to multi-threaded or multi-process systems running on a single processor machine, in distributed systems several processing steps can really happen at the same time. Coordinating such systems is far from simple. Even basic coordination, such as providing a common time, requires sophisticated protocols. Concurrency can result in a number of problems, such as non-determinism, deadlocks, and race conditions. • Scalability: Since different parts of a system, such as clients and servers, are distributed and therefore more or less independent, it is not always possible to know in advance how many of these different systems are actually available and how high the commu- nication load is going to be at a certain time. For example, it is hard to determine the number of clients for a Web server: at certain peak times, many more clients than expected might want to access the content of a Web site. The software, the hardware, and the network must be able to scale up to handle this additional load at any time - or at least fail gracefully. • Partial Failure: In systems that run on a single machine, ideally in a single process, a failure, such as a hardware problem or a fatal soft- ware bug, usually has a simple consequence: the program stops running - completely. It is not possible that only parts of the program stop, which is what partial failure is all about. In distrib- uted systems, this is different: it is very well possible that only a part of the overall system fails. Designers might have considered this behavior - see the failover discussion above. However, in many systems it can become very difficult to detect what part of a system has actually failed, and how to recover. For example, when a client wants to communicate with a server and does not receive a reply, this can have many reasons: The server process may have modified 2:49 PM 25 June 2004 Introduction.fm
crashed. Or, the server machine may have gone down. Or, the process has not crashed, but only overloaded and it may just take more time to answer the request. Finally, there might be no problem with the server at all, the network might be broken, over- loaded, or unreliable. Depending on how the system failed, different ways of recovery are necessary. Therefore, the real problem is to determine the actual cause of the failure. It is some- times impossible for clients to detect failures. There are many algorithms to detect such problems (see [TS02]), but none of them is simple, and all imply an additional performance overhead. As a bottom line, you should only distribute your system if distribution is really needed. Distribution adds complexity, concurrency, ineffi- ciency, and other potential problems to your application that would not occur in a non-distributed context. Note that we do not advocate to avoid the use of distributed systems; it is just important to carefully evaluate when to distribute and what to distribute - check also Fowler’s “First law of distributed object design” in [Fow03]: “Don't distribute your objects!”
Communication Middleware Distributed systems can be built directly on top of low-level network protocols. For instance, communication can be based on TCP/IP sockets which allow distributed processes to pass each other messages using send and receive operations directly [Ste98]. But this yields a number of problems because developers have to deal with low-level networking details. In particular, such systems: • are usually not easy to scale, • are typically rather cumbersome and error prone to use for developers, • are hard to maintain and change, and •do not provide transparency of the distributed communication. A common solution to these problems is to add an additional software layer, called Communication Middleware, or simply Middleware, that hides the heterogeneity of the underlying platforms and provides transparency of distributed communication for application developers. In this context, transparency aims at making remote invocations as modified 2:49 PM 25 June 2004 Introduction.fm
similar as possible to local invocations. However, since remote invoca- tions introduce new kinds of errors, latency, and so forth, complete transparency is not possible. This aspect will be addressed in more detail later in this book. The figure below shows that the middleware hides the network services and other details of remote communication from clients and server applications.
Client Server Application Application
Server Client Application
Middleware
Network Network Services Services
Operating Operating System System Kernel Kernel
Network
The middleware is an additional software layer that sits between the network services, offered by the operating system, and the application layer hosting the client and server application. Due to the additional layer the middleware hides the heterogeneity of the underlying plat- forms from application developers. Clients and server applications are usually not allowed to bypass the middleware layer in order to access low-level network services directly. As outlined in the next section, different middleware systems are based on different remoting styles, such as remote procedure calls or message passing. Whatever remoting styles is used today in an application, the application developer should be shielded from the details of how the respective middleware implementation really communicates over the modified 2:49 PM 25 June 2004 Introduction.fm
network. The middleware takes care of the specifics of realizing the remoting styles using available lower-level services. Middleware provides a simple, high-level programming model to the developers, hiding all the nitty-gritty details as good as possible. For example, a middleware might take care of connection handling, message passing, and serialization, but does not try to hide the specific errors conditions that are introduced by the fact that an invocation target is located remote. Middleware specifications and products are available for all popular remoting styles. The technology projections introduced later in the book show some examples of distributed objects middleware.
Remoting Styles There are a number of different remoting styles used in today’s middle- ware systems. In this section, we introduce some popular remoting styles and explain a few prominent example of middleware systems for each of the styles. Historically, distributed computing is derived from simple file transfers. File transfer was the original means of program-to-program communi- cation. And it is still the basis of many mainframe systems today. The principle of file transfers is that each program works on a physical file. The programs accept files as its input and create new files, or modify existing files, after that the files are exchanged with the next program. While file transfer has proven effective for solving many problems, the issues of latency and resource contention have made it unattractive for today’s high-speed, high-volume systems. In the following sections, we take a brief look at the following basic remoting styles that are used instead of file transfer today. There are systems that • use the metaphor of a remote procedure call (RPC), • use the metaphor of posting and receiving messages, • utilize a shared repository, or • use continuous streams of data. This book mainly focusses on object-oriented variants of the RPC style. However, all of the mentioned remoting styles can be used to imple- ment the others. Also, there are interrelations between the styles, such modified 2:49 PM 25 June 2004 Introduction.fm
as a shared repository accessed with RPC or asynchronous RPC invo- cations sent as messages. Because of these interrelations among the remoting styles, it is impor- tant to understand the diversity in remoting styles in order to properly understand the pattern language contained in this book. Also, it is important to understand that there are many other remoting styles that are based on top of the basic remoting styles. Examples of such more advanced remoting styles are code mobility, peer-to-peer (P2P), remote evaluation, GRID computing, publish/subscribe systems, transaction processing, and many others. Note that these more high-level remoting styles are often implemented using the basic styles, or as variants of them. However, the users of these styles are not confronted with their internal realization. For example, the user of a P2P system, which is based on RPC, does not have to deal with the internal RPC mecha- nisms, nor with the naming service used for ad hoc lookup of peer services. In the chapter Related Concepts, Technologies, and Patterns we discuss how some of these more advanced remoting styles can be realized using the pattern language presented in this book. When new remoting styles emerge, usually no complete, industry-level implementation is available. Thus, parts of the system have to be built by hand using low- level remoting styles. Consider a small, custom publish/subscribe system built on top of an OO-RPC middleware: in order to build such a system, the internals of the OO-RPC middleware, as well as the possible ways to extend, customize, and integrate it, have to be well understood. The pattern language in this book provides a foundation for understanding distributed object middleware systems in such a way.
Remote Procedure Calls Remote procedure calls extend the well-known procedure call abstrac- tion to distributed systems. They aim at letting a remote procedure invocation behave as if it were a local invocation. Use of low-level network protocols requires developers to directly invoke the send and receive operations of the respective network protocol implementations. Remote Procedure Call (RPC) systems [BN84] introduce a simple but powerful concept to avoid this problem: modified 2:49 PM 25 June 2004 Introduction.fm
programs are allowed to invoke procedures (or operations) in a different process and/or on a remote machine. In RPC, two different roles are distinguished: clients and servers. Clients invoke operations. Servers accept operations. When a client process invokes an operation in a server process, the invoking client process is suspended, and the execution of the invocation in the server takes place. After, the server sends the result back to the client and the result is received, the client resumes its work. A server provides a well defined set of operations which the client can invoke. To the client developer these operations look almost exactly like local operations: they typically have an operation name, parame- ters, and a return type, as well as a way to signal errors. One major difference to ordinary operations is that additional errors might occur during a remote invocation, for instance, because the network fails or the requested operation is not implemented at the server. These errors can be signaled to the client, for instance, as specific kinds of exceptions. As an extension to the RPC style, there are also many asynchronous RPC variants. That is, a client immediately resumes its work after it has invoked a remote operation, without blocking until the result becomes available. There are two different, popular flavours of remote procedure call systems: • Those that really use the procedure-based approach, where a server application provides only the specified operations to clients, and • object-oriented remote procedure call systems (OO-RPC), where a server application hosts a set of objects that provide the operations to clients as part of their public interface. The internal mechanisms are in both variants similar; however, in OO- RPC systems there is the notion of object identity – meaning that clients can address objects separately. Also, a distributed object can have its own state whereas RPC-based systems often provide stateless services. In addition, the OO-RPC approach maps more naturally into today’s object-oriented way of software development and is therefore used almost exclusively in new systems. modified 2:49 PM 25 June 2004 Introduction.fm
The figure below shows an example of an OO-RPC system: the OO- RPC middleware allows clients to transparently access objects within a server process.
Client Application Server Application server object server object client server object object server object process
invokeinvoke method method
invokereturn resultmethod (OO-)RPC-Middleware
Popular procedure-based systems are the Distributed Computing Environment (DCE) [Ope91] and Sun RPC [Sun88]. DCE, for instance, was developed by the Open Software Foundation. Originally designed as a RPC middleware for Unix platforms, it has later been ported to all major operating systems, including Windows variants and VMS. DCE introduces a typical and straightforward way of performing RPC, which allows to automatically locate the server hosting the operations of interest (during a process called binding): first, the server registers a procedure as an endpoint with the DCE daemon running within the server’s machine, then it registers the service in a directory server that might run on a different machine. When the client wants to access the remote procedure, it first looks up the server in the directory server. The server is then asked for the endpoint. This endpoint is then used to invoke the remote procedure. Even though DCE is a procedure-based middleware, it also provides extensions for supporting remote objects. Nowadays there are many popular OO-RPC middleware systems specifically designed for distributed object communication. Examples of such systems are: • Common Object Request Broker Architecture (CORBA) (see CORBA Technology Projection Chapter), modified 2:49 PM 25 June 2004 Introduction.fm
• Microsoft’s .NET Remoting (see .NET Remoting Technology Projec- tion Chapter). • Web Services (see Web Services Technology Projection Chapter), • Microsoft’s DCOM [Gri97], and • Sun’s Java RMI [Gro01] These middleware systems and their concepts are the primary focus of this book.
Message Passing While the (OO-)RPC middleware uses the metaphor of a procedure (or operation) invocation, the message passing metaphor is different. Messages are exchanged between peers, and the peers are free to consume the messages as and when they like. Message passing is inher- ently asynchronous.
Client Application Server Application
message Queue message
process reply Queue reply
Messages are not passed from client to server application directly, but through intermediate message queues that store and forward the messages. This has a number of consequences: Senders and receivers of messages are decoupled; they do not need to know each other’s iden- tity. A sender just puts messages into a certain queue and does not necessarily know who consumes the messages. For instance, a message might be consumed by more than one receiver. Receivers consume messages by “listening” to queues. The two peers of a remote communication are timely decoupled: a sender can put a message into the message queue while there is no receiver running or connected. Receivers can later get the messages from the queue. Thus, the messaging style is inherently asynchronous. modified 2:49 PM 25 June 2004 Introduction.fm
Replies as part of the middleware are not foreseen. If applications require replies, they have to be modelled and sent as separate messages. Many messaging protocols provide a reliable means of message delivery, such as an acknowledgement scheme. Further, the ordering of messages is ensured, so that receivers process messages in the same order as they were sent, even if messages had to be retransmitted in between. Thus, messaging provides a way to tolerate temporal failures of the peers. Also, many message passing systems guarantee that once the message is put into the queue it will be delivered exactly once and only once to the receiver. Consequently, messaging systems can provide a high level of reliability to their users. The message passing style allows for many variations in the implemen- tations. Some systems distinguish between queues where there is one receiver, or several. In the latter case, each message is delivered to each receiver. This is often referred to as publish/subscribe systems. Typically, messages are delivered asynchronously, as explained above. However, some systems allow for synchronous delivery, blocking the sender until the message has been delivered successfully. Similar to RPC invocations, the message is sent to the receiver, and then a response is awaited. This mode is provided by messaging systems, for instance, to support typical client/server transaction characteristics. As a side effect, this technique can be used to coordinate concurrent systems. Messages can be persistently buffered in the message queue in case the receiver is not accessible. A message can then be guaranteed to be delivered exactly once. Several messages can be delivered to one or more clients atomically in the context of a transaction. However, there are some limitations to transaction processing, when using the message passing style. For instance, sending a message and receiving the same message in one distributed transaction is not possible. This would violate the desired transaction property “isolation” because entering a message into a destination and removing a message from a destination are two distinct operations that must be executed in two different transactions.
modified 2:49 PM 25 June 2004 Introduction.fm
As discussed above, the message passing style is conceptually different from a remote procedure call for the reasons given above. Technically however, it is easily possible to implement RPC semantics with a message passing system, or implement message passing using RPC. We will discuss the latter variant briefly in the Invocation Asynchrony Patterns Chapter. There are a number of simple message passing systems, including Berkeley Sockets [Lem97] and the Message-Passing Interface (MPI) [Qui03], allowing mainly for asynchronous communication, and a number of message queueing systems allowing also for persistent messaging. Message-Oriented Middleware (MOM) extends the concept of such simple message passing systems with support for inter-process messaging and persistent message queueing. That is, reliable commu- nication is enabled: the MOM stores messages intermediately, without having the sender or receiver actively participate in the network transfer. Once a message is put into a queue it remains there until it is removed. This model allows for loosely-coupled communication: a receiver does not have to directly consume a message, when it arrives. This way, for instance, a crash of the server can be tolerated. Popular MOM products are IBM’s WebSphere MQ (formerly MQ Series) [Ibm04], JMS [Sun04c], Microsoft’s MSMQ [Mic04a], and Tibco [Tib04]. We discuss further details of messaging and how it relates to the pattern language presented in this book in Chapter Related Concepts, Technologies, and Patterns.
Shared Repository A shared repository is based on the idea that there is some shared data space, and independent, remote clients interact by reading and writing to the shared data space. There are two basic roles in the shared repository remoting style: the shared repository, which is also referred to as the Blackboard [BMR+96], and its clients. The shared repository offers a small interface consisting
modified 2:49 PM 25 June 2004 Introduction.fm
of access primitives to the clients. Note that the data access in a shared repository is often implemented using RPC mechanisms.
client app client app client app client app add add retrieve delete
Shared Shared Shared Repository Repository Repository Interface Interface Interface process process process
Shared Repository
Systems for shared repositories exist in many different flavours. The most simple variant is a shared memory or file space with which different processes interact. When memory and file space are shared among different machines, a distributed system is created. There are many more high-level shared repositories. In addition to simply sharing data, the solutions have to: • handle problems of resource contention, for instance by locking accessed data, • abstract from location of the shared data, the data storage, or the client, • optimize performance and scalability, and • provide additional services, such as security. Some systems even introduce high-level access mechanisms, such as query languages or tuple spaces [GCCC85]. Databases are one way to implement a shared repository. In a database, the database management system (DBMS) provides mechanisms for locking and unlocking the data, and also provides standard mecha- nisms for creating, deleting, searching, and updating information. modified 2:49 PM 25 June 2004 Introduction.fm
Most DBMSs provide query languages for high-level data access. Shared databases might utilize transaction processing monitors to support distributed transactions. Some approaches, such as Linda [GCCC85] or PageSpace [CTV+98], are based on the concept of Virtual Shared Memory (VSM). VSM is a shared object repository that can be used to store shared data. It is virtual in the sense that no physically shared memory is required. The underlying data structure of Linda is a tuple space: processes do not communicate directly, but rather by adding and removing tuples (ordered collections of data) to and from the tuple space. The tuples are then stored in shared memory. Tuple space based systems typically provide only a very small set of operations on the shared tuple set. It has been demonstrated that many problems of distributed and concur- rent applications can be solved very elegantly using this approach. Other examples of tuple-based systems include Sun’s JavaSpaces [FHA99] and IBM’s TSpaces [Ibm00].
Streaming While the previously explained styles used discrete and complete units of data that are exchanged (invocation requests, messages, or data items); it is different for stream-based systems: here, information is exchanged as a continuously flowing stream of data. The two different roles to be distinguished are streaming servers and clients receiving streams. There are several different types of streams (see [TS02]): • Asynchronous streams consist of data where the sequence of packets is important, but not the timing. An example could be a file transmitted over a TCP/IP socket. Whether the transfer rate is slow or fast does not matter. A slower rate will result in a longer transfer time of the file, but the file is nonetheless transferred correctly. • Synchronous streaming is inherently time dependent. The data packets have to be transferred at a certain minimum rate, other- wise the data may be useless to the receiver. Thus there is maximum delay between two data packets. For example, subse- quent measurements by a sensor might have to be transmitted at a
modified 2:49 PM 25 June 2004 Introduction.fm
certain rate to achieve the necessary accuracy of a subsequent calculation. • Isochronous streaming has even more rigid requirements regarding timing. Data items have to be transferred on time, not just in time. That is, there is a maximum delay between data packets as well as a minimum delay. Typical examples are audio or video streams. Stream-based systems can follow a one-to-one or one-to-many streaming concept. In the latter case, depending on the streaming tech- nology, the stream might still have to be transported separately to each receiver.
Client
consume Server Application stream
Client
create consume stream stream
Client
consume stream
In the figure above an example configuration is shown: one stream server application provides continuous streams of data to multiple clients. Often, streams have to be received by several clients at a time. In a web-based video or audio broadcast, there is typically a single stream server and a relatively large number of clients. The necessary bandwidth must be ensured on the whole data path, from the server to all of the clients.
modified 2:49 PM 25 June 2004 Introduction.fm
The primary challenge with stream based systems, especially isochro- nous ones, is to ensure the necessary timing requirements, typically referred to as quality of service (QoS). Stream-based systems are not considered in this book.
modified 2:49 PM 25 June 2004 Introduction.fm
modified 2:49 PM 25 June 2004 Introduction.fm
Pattern Language Overview
This chapter provides an overview of the pattern language described in the next chapters. We start off by recasting the Broker pattern from POSA1 [BMR+96] as the entry point into the pattern language that follows. From our perspective, the Broker pattern is a compound pattern that is typically implemented using a number of patterns from our pattern language. Especially the patterns in the Basic Remoting Patterns chapter are used almost any Broker architecture. Next, we introduce two important participants of Broker-based systems in detail: the remote object and the server application. This is important because these two participants are used in almost any distributed object application and thus are ever-present throughout our pattern language.
modified 2:49 PM 25 June 2004 PatternOverview.fm
Broker
You are designing a distributed software system. Distributed software system developers face many challenges that do not arise in single-process software. One main challenge is the communication across unreliable networks. Other challenges are the integration of heterogeneous components into coherent applications, as well as the efficient usage of networking resources. If developers of distributed systems must master all these challenges within their application code, they will likely loose their primary focus: to develop applications that resolve their domain-specific responsibili- ties well. Communication across networks is more complex than local communi- cation because connections need to be established, invocation parameters have to be transmitted, and a new set of possible errors has to be coped with. This requires handling invocations to local objects differently than invocations to remote objects. Additionally, tangling remote communication concerns with the overall application structure complicates the application logic. From an object-oriented program- ming perspective, it would be ideal, if the remote objects could be invoked as if they were local objects. Also, the location of the remote objects should not be hard-wired into client applications. It should be possible to host remote objects on different machines without adaptation of the client’s program code. Therefore: Separate the communication functionality of a distributed system from its application functionality by isolating all communication related concerns in a BROKER. The BROKER hides and mediates all communication between the objects or components of a system. A BROKER consists of a client-side REQUESTOR to construct and forward invocations, as well as a server-side INVOKER that is responsible for invoking the operations of the target remote object. A MARSHALLER on each side of the communications path handles the transformation
modified 2:49 PM 25 June 2004 PatternOverview.fm
of requests and responses — from programming-language native data types into a byte array that can be sent over the wire.
Process A Process B Remote Client Object
5) invoker operation 1) submit request
Requestor Invoker 2) marshal request 3) forward 4) unmarshal Machine Boundary Machine
Marshaller Marshaller
The client submits a request to the REQUESTOR that mar- shalls the request and transmits it across the network. The server side INVOKER receives the invocation request and in- vokes the remote object.
Local BROKER components on client and server side enable the exchange of requests and responses between the client and the remote object. In addition to the core patterns consisting of REQUESTOR, INVOKER, and MARSHALLER, the BROKER typically relies on the following patterns:
•A CLIENT PROXY represents the remote object in the client process. This proxy has the same interface as the remote object it repre- sents. The CLIENT PROXY transforms invocations of its operations into invocations of the REQUESTOR that, in turn, is responsible for constructing the request and for forwarding it to the target remote object. A CLIENT PROXY is thus used to let remote operation invoca- tions look like local operation invocations from a client’s perspective. An INTERFACE DESCRIPTION is used to make the remote object’s interface known to the clients. The client makes use of the INTERFACE DESCRIPTION in the form of a CLIENT PROXY. • LOOKUP allows clients to discover remote objects. This ensures that the location of remote objects does not need to be hard-wired into modified 2:49 PM 25 June 2004 PatternOverview.fm
the system. Remote objects can be moved to other hosts without compromising system integrity, and the location of remote objects is in control of the server developers. •The CLIENT REQUEST HANDLER and SERVER REQUEST HANDLER handle efficient sending, receiving, and dispatching of requests. Their responsibility is to forward and receive request and response messages from and to the REQUESTOR and the INVOKER, respectively. • REMOTING ERRORS are used to signal problems of remote communi- cation to the client side. REMOTING ERRORS are caused either by technical failures in the network communication infrastructure or by problems within the server infrastructure. The REQUESTOR and INVOKER are responsible for forwarding REMOTING ERRORS to the client, if they cannot handle the REMOTING ERROR on their own. In the following section we take a closer look at two important, addi- tional participants of the BROKER-based applications: remote objects and the server application. Note that these two are not participants of the BROKER pattern itself. They are merely necessary in applications that use a BROKER as their communications backbone.
Remote Object Consider you are using or building a distributed object middleware that is used to access objects remotely. Clients need to access func- tionality provided by remote application objects. In many respects, accessing an object over a network is different from accessing a local object. An invocation has to cross process and machine boundaries. Network latency, network unreliability, and many other distinctive properties of network environments play an important role and need to be “managed” for the developer. In particular: • For a remote invocation, machine and process boundaries have to be crossed. An ordinary, local operation invocation is not suffi- cient, because the operation invocation has to be transferred from the local process to the remote process, running on the remote machine. • Using memory addresses to define object identity will not work anymore. While unique in the address space of one process, they
modified 2:49 PM 25 June 2004 PatternOverview.fm
are not necessarily unique across process boundaries and espe- cially machine boundaries. • Compared to local invocations, invocations across a network involve unpredictable latency. Because networks must be consid- ered to be unreliable, clients must deal with new kinds of errors. Further, the communication path should be as short as possible, limiting the number of network hops. The distributed object middleware provides solutions for these funda- mental issues of accessing objects remotely using a BROKER architecture. The application logic, implemented by server developers is provided in form of remote objects. These remote objects are important conceptual building blocks for these distributed applications. Each remote object provides a well-defined interface to be accessed remotely; that is, the remote client can address the remote object across the network and invoke its operations. The BROKER transfers local invo- cations from the client side to a remote object, running within the server.
Process A Process
Remote Object ID: 4711
Client 1) <
Machine Boundary Application
The server application instantiates a remote object. Then clients can access the remote object using the functionality provided by the distributed object middleware.
Remote objects have a unique OBJECT ID in their local address space, as well as means to construct an ABSOLUTE OBJECT REFERENCE. The ABSO- LUTE OBJECT REFERENCE is used to reference and subsequently access a remote object across the network. A remote object is in first place a logical entity in the scope of the distributed object middleware. It can be realized by different program- ming language entities. In an object-oriented language usually a modified 2:49 PM 25 June 2004 PatternOverview.fm
remote object is realized as an object of the programming language. However, that does not mean that each remote object is realized by exactly one programming language object or that all requests to one remote object are served by the same programming language object. For instance, the resource optimization pattern POOLING lets a pool of multiple objects handle requests for a remote object. In non-object- oriented programming languages other structures than objects are used to implement the remote object. To distinguish the runtime entity from the remote object as a logical entity, we call the entity that repre- sents a remote object at runtime the servant. In cases, where there is exactly one servant for one remote object, we simply use the term remote object as a synonym for both, the remote object and its servant. Clients need to know the remotely accessible interface of a remote object. A simple solution is to let remote clients access any operation of the remote object. But perhaps some local operations should be inacces- sible for remote clients, such as operations used to access the distributed object middleware. Thus each remote object type defines or declares its remotely accessible interface. Remote objects are used to extend the object-oriented paradigm across process and machine boundaries. However, accessing objects remotely always implies a set of inherent problems, such as network latency and network unreliability, that cannot be completely hidden from devel- opers. Different distributed object middleware systems hide these issues to a different degree. When designing a distributed object middleware, there is always a trade-off between possible control and ease-of-use. To a certain extent, these problems can be avoided by following the principle “Don’t distribute your objects” [Fow03]. However, this only works as long as the application problem is not inherently distributed in nature. If distribution is necessary, make sure you co-locate objects that require a lot of communication and design your interfaces in ways that allow for exchanging as much data as possible within one remote call - reducing the number of remote invocations to the bare minimum (see the Data Transfer Object and Facade patterns in [Fow03]). In case of errors that are related to the remote nature of a remote object, make sure there is a way to signal these REMOTING ERRORS to the client in a well defined manner. modified 2:49 PM 25 June 2004 PatternOverview.fm
Server Application Remote objects need a server application that has to perform the following tasks: • The constituents of the distributed object middleware have to be created and configured. • The remote objects need to be instantiated and configured, if not done by the distributed object middleware constituents. • Remote objects need to be advertised to interested clients. • Individual remote objects need to get connected to distributed applications. • If no longer needed, remote objects need to be destroyed or recycled. To resolve these issues, use a server application as a building block that connects all parts of the distributed application. The server application instantiates and configures the distributed object middleware, as well as the remote objects on top of it. On shutdown, the server application has to ensure to free used resources by destroying remote objects, announcing their unavailability, and destroying the distributed object middleware instance. Depending on how sophisticated the distributed object middleware is, the server application might delegate many of the remote object life- cycle management tasks to the distributed object middleware.
The server application creates an instance of a remote ob- ject, hands it over to the lifecycle manager of the distribut- modified 2:49 PM 25 June 2004 PatternOverview.fm
ed object middleware, and finally announces the availability of the remote object by registering it with a lookup service. The server application bundles remote objects that conceptually belong together, and handles all object management tasks with respect to the distributed object middleware.
modified 2:49 PM 25 June 2004 PatternOverview.fm
Overview of the Pattern Chapters
The patterns mentioned so far detail the BROKER pattern and will be described in the Basic Remoting Patterns chapter of this book. The following illustration shows the typical interactions of patterns.
INTERFACE DESCRIPTION
s e f de ib o in s r e t c sc c e ri e a rf be d rf ac s te e in of CLIENT PROXY Remote Object MARSHALLER
u s u e p s s o r t r e t e o d u h fo g e s n q e c b s in - t o u ll m s i u e a t e s a s a fo i u h t r r r p a s l s e s d s q h is c t r e a a u u l d o m q es lin v re ts g in REQUESTOR REMOTING INVOKER raises raises ERROR u
r s s e s e e o e t q s h n s c u e r t ts d t a e o s i is a s s ra e p e t s is u d q e r CLIENT REQUEST SERVER REQUEST communicates HANDLER with HANDLER
The chapters following the Basic Remoting Patterns chapter present patterns that extend the elementary patterns; the remainder of this section will provide an brief overview of them. The patterns in the Identification Patterns chapter deal with issues regarding identification, addressing, and lookup of remote objects. It is important for clients to find the correct remote object within the server application. This is done by the assignment of logical OBJECT IDS for each remote object instance. The client embeds these OBJECT IDS in invo- cations so that the INVOKER can find the correct remote object. However, this assumes that we are able to deliver the message to the correct server application - because in two different server applications two different objects with the same OBJECT ID might exist. An ABSOLUTE OBJECT REFERENCE extends the concept of OBJECT IDS with location infor- mation. An ABSOLUTE OBJECT REFERENCE contains, for example the hostname, the port, and the OBJECT ID of a remote object. modified 2:49 PM 25 June 2004 PatternOverview.fm
LOOKUP is used to associate remote objects with human readable names and other properties. The server application typically associates prop- erties with the registered remote object. The client must only know the ABSOLUTE OBJECT REFERENCE of the lookup service instead of the poten- tially huge number of ABSOLUTE OBJECT REFERENCES of the remote objects it wants to communicate with. The LOOKUP pattern simplifies the management and configuration of distributed systems as clients can easily find remote objects, while avoiding tight coupling between them. The interactions of the patterns are visualized in the following depen- dency diagram.
SERVER REQUESTOR INVOKER Client APPLICATION s n s ig t s s c s a r n u i r e t t s s t s s e u i c s s n g u e e o looks up j e s c objects in r b o
ABSOLUTE OBJECT LOOKUP OBJECT ID is part of REFERENCE
m a identifies p s p s ro ie p tif e en rt id ie ly s ue t iq o un Remote Object
The Lifecycle Management Patterns chapter deals with the management of the lifecycle of remote objects: While some remote objects need to exist all the time, others need to be available only for a limited period of time. Further, the activation and deactivation of remote objects might be coupled with additional tasks. Lifecycle management strategies are used to adapt to specifics of the lifecycle of remote objects and their usage. The strategies have a strong influence on the overall resource consumption of the distributed appli- cation. The Lifecycle Management Patterns describe some of the most common strategies used in today’s distributed object middleware. The three basic lifecycle strategy patterns have the following focus:
modified 2:49 PM 25 June 2004 PatternOverview.fm
• STATIC INSTANCES are used to represent “fixed” functionality in the system. Their lifetime is typically identical to the lifetime of their server application. • PER-REQUEST INSTANCES are used for highly concurrent environ- ments. They are created for each new request and destroyed after the request. • CLIENT-DEPENDENT INSTANCES are used to represent client state in the server. They rely on the client to explicitly instantiate them. The lifecycle strategies patterns internally make use of a set of specific resource management patterns, which are:
• LEASING is used to properly release CLIENT-DEPENDENT INSTANCES when they are no longer used. • LAZY ACQUISITION describes how to activate remote objects on demand. • POOLING manages unused remote object instances in a pool to opti- mize reuse.
For state management, PASSIVATION takes care of temporarily removing unused instances from memory and storing them in a persis- tent storage. Upon request, the instances are restored again.
modified 2:49 PM 25 June 2004 PatternOverview.fm
The patterns and their relationships are shown in the following figure.
SERVER APPLICATION LIFECYCLE MANAGER Client instantiates instantiates instantiates
CLIENT-DEPENDENT STATIC INSTANCE PER-REQUEST INSTANCE INSTANCE
s
s requires
e
e
z
z
i i s e
m s m z
i ie i i
t l t p im
p p t im p
o o o
LAZY ACQUISITION POOLING LEASING
PASSIVATION may use may use
The Extension Patterns chapter deals with patterns that are used to extend a distributed object middleware. Examples of such extensions are the support for security, transactions, or even the exchange of communication protocols. In order to handle aspects such as security or transactions, remote invo- cations need to contain more information than just the operation name and its parameters: some kind of transaction ID or security credentials need to be transported between client and server. For that purpose INVOCATION CONTEXTS are used: they are typically transparently added to the invocation on client side and read out on server side by the REQUESTOR, CLIENT/SERVER REQUEST HANDLERS, and INVOKER, respectively. When the invocation process needs to be extended with behavior, for instance, when evaluating security credentials in the client and the server, INVOCATION INTERCEPTORS can be used. For passing information between clients and servers, INVOCATION INTERCEPTORS use the already mentioned INVOCATION CONTEXTS. modified 2:49 PM 25 June 2004 PatternOverview.fm
Another important extension is the introduction and exchange of different communication protocols. Consider again the security example: a secure protocol might be needed that encrypts the invoca- tion data before it is sent and received using the CLIENT or SERVER REQUEST HANDLER, respectively. While simple REQUEST HANDLERS use a fixed communication protocol, PROTOCOL PLUG-INS make the REQUEST HANDLERS extensible to support multiple communication protocols. The relationships of the patterns are illustrated in the following figure.
Client
es us Remote Object
ENT uses INVOCATION OXY p uses u es INTERCEPTOR ro s id r h vid e ov fo oo e s r k s p s creates/ s ok f ho uses or
REQUESTOR INVOKER
INVOCATION CONTEXT
uses tr uses s a rt n o s p p s o n rt a s tr
CLIENT REQUEST SERVER REQUEST communicates w ith HANDLER HANDLER pl o uge int d int ged o plu PROTOCOL PLUG-IN
The Extended Infrastructure Patterns chapter deals with specific imple- mentation aspects of the server-side BROKER architecture.
The LIFECYCLE MANAGER is responsible for managing activation and deactivation of remote objects - by implementing the lifecycle manage- ment strategies described in the Lifecycle Management chapter, typically as part of the INVOKER. To be able to configure groups of remote objects—instead of config- uring each object separately—with regards to lifecycle, extensions, and other options, CONFIGURATION GROUPS are used.
modified 2:49 PM 25 June 2004 PatternOverview.fm
In order to be able to monitor the performance of various parts of the system, such as the INVOKER, the SERVER REQUEST HANDLER, or even the remote objects themselves, QOS OBSERVERS can be used. They help ensuring specific quality of service constraints of the system. To make infrastructure objects of the distributed object middleware follow the same programming conventions as remote objects, while making them inaccessible from remote sites, LOCAL OBJECTS can be used. Typical LOCAL OBJECTS are the REQUESTOR, the LIFECYCLE MANAGER, the QOS OBSERVERS, and so forth.
ABSOLUTE OBJECT REFERENCES identify a remote object in a server. If the remote object instances are to be decoupled from the ABSOLUTE OBJECT REFERENCE, an additional level of indirection is needed. LOCATION FORWARDERS allow this, they can forward invocations between different server applications. This way load balancing, fault tolerance, and remote object migration can be implemented. The following figure shows the Extended Infrastructure Patterns and their relationships.
QOS OBSERVER s
s r
r o o t rs it i ito n n n o o o m m m im p le INVOKER m e REQUEST HANDLER Remote Object n te d a n a s tio p ca r p lo fo e s y f a de nd o vi nc a rs ro are ts LOCATION p p s e li ns p s k ra ou s e
t manages FORWARDER gr e z for lifecycle ni ga LOCAL OBJECT
or s
s LIFECYCLE MANAGER
'
e
t
t n
a CONFIGURATION
e
d
i
l
p
c n
u GROUP
o
s
i
e
t
e
c
p
r z
i
u
m
m
o
i u
t s
ABSOLUTE OBJECT s
p
e
n
r o
REFERENCE o c
Server Application
modified 2:49 PM 25 June 2004 PatternOverview.fm
The last patterns chapter in this book describes Invocation Asynchrony Patterns. This chapter deals with how to handle asynchronous invoca- tions. It presents four alternative patterns that extend ordinary synchronous invocations:
• FIRE AND FORGET describes best-effort delivery semantics for asyn- chronous operations that have void return types. • SYNC WITH SERVER sends—in addition to the semantics of FIRE AND FORGET—an acknowledgement back to the client once the opera- tion has arrived on the server-side. • POLL OBJECTS allow clients to query the distributed object middle- ware for responses to asynchronous requests. • RESULT CALLBACK actively notifies the requesting client of a asyn- chronously arriving responses.
MESSAGE QUEUES allow for queueing messages in the CLIENT REQUEST HANDLER and SERVER REQUEST HANDLER. They are the foundation for message-oriented communication. The following figure illustrates the patterns and their interactions.
REQUEST HANDLER requests and requests responses queuing
MESSAGE QUEUE p a r vi ov lt id su es re r s e e su id lt ov v pr ia
POLL OBJECT RESULT CALLBACK alternatives extends with extends ext end s w result ith re sult
FIRE AND FORGET SYNC WITH SERVER extends reliably
modified 2:49 PM 25 June 2004 PatternOverview.fm
modified 2:49 PM 25 June 2004 PatternOverview.fm
Basic Remoting Patterns
This chapter presents patterns that constitute the basic building blocks of a distributed object middleware. These patterns are used in almost every middleware implementation. Before presenting the patterns, we give an overview of the patterns and their dependencies. At the end of this chapter, we show how the participants of the patterns interact with each other. Distributed object middleware provides an infrastructure for clients to communicate with remote objects on a remote server. Remote objects are implemented as ordinary objects on the server side. The client invokes an operation of a local object and expects it to be forwarded to the remote object. To make this happen, the invocation has to cross the machine boundary. A REQUESTOR constructs a remote invocation on client side from parameters such as remote object location, remote object type, operation name, and arguments. A client can either use a REQUESTOR directly or use a CLIENT PROXY. The CLIENT PROXY is a local object within the client process that offers the same interface as the remote object. This interface is defined using an INTERFACE DESCRIPTION. Internally, the CLIENT PROXY uses the REQUESTOR to construct remote invocations.
The REQUESTOR on the client side uses a CLIENT REQUEST HANDLER to handle network communication. On the server side, the remote invoca- tions are received by a SERVER REQUEST HANDLER. It handles message reception in a efficient and scalable way, and subsequently forwards invocations to the INVOKER, once the message has been received completely. The INVOKER dispatches remote invocations to the respon- sible remote object using the received invocation information. The parameters passed between client and server are serialized and de- serialized using a MARSHALLER. If the client experiences technical prob- lems in communicating with the server, or if the server has internal technical problems, this is returned to the CLIENT REQUEST HANDLER and signalled to the client using a REMOTING ERROR. modified 2:50 PM 25 June 2004 Basic.fm
INTERFACE DESCRIPTION
s e f de ib o in s r e t c sc c e ri e a rf be d rf ac s te e in of CLIENT PROXY Remote Object MARSHALLER
u s u e p s s o r t r e t e o d u h fo g e s n q e c b s in - t o u ll m s i u e a t e s a s a fo i u h t r r r p a s l s e s d s q h is c t r e a a u u l d o m q es lin v re ts g in REQUESTOR REMOTING INVOKER raises raises ERROR u
r s s e s e e o e t q s h n s c u e r t ts d t a e o s i is a s s ra e p e t s is u d q e r CLIENT REQUEST SERVER REQUEST communicates HANDLER with HANDLER
modified 2:50 PM 25 June 2004 Basic.fm
Requestor
A client needs to access one or more remote objects on a remote server.