Building Distributed Applications with Galaxy

Galaxy 2.0, a cross-platform toolset for building complex distributed applications, lets you write applications that can communicate with other Galaxy applications running on any platform.


March 01, 1995
URL:http://www.drdobbs.com/parallel/building-distributed-applications-with-g/184409522

Figure 1


Copyright © 1995, Dr. Dobb's Journal

Figure 2


Copyright © 1995, Dr. Dobb's Journal

Figure 3


Copyright © 1995, Dr. Dobb's Journal

Figure 1


Copyright © 1995, Dr. Dobb's Journal

Figure 2


Copyright © 1995, Dr. Dobb's Journal

Figure 3


Copyright © 1995, Dr. Dobb's Journal

MAR95: Building Distributed Applications with Galaxy

Building Distributed Applications with Galaxy

Consumers and providers interact via sessions and statements

Stan Dolberg

Stan is a vice president at Visix Software in Reston, VA. He can be reached at [email protected].


Today's application developers face a major challenge when scaling up from proof-of-concept client/server applications to large, multiplatform network applications. All too often, an application originally written as a single-platform, 4GL program and then scaled up to a system spanning many departments, platforms, languages, and networks is as robust as a skyscraper built out of wood with two-by-fours.

Galaxy 2.0 is a cross-platform toolset for building complex distributed applications. Galaxy consists of class libraries with about 3500 API entry points, plus GUI design tools and a distributed-services infrastructure. The environment, which is available for C or C++, runs on Windows, NT, OS/2 2.1, SunOS, Solaris, HP-UX, Ultrix, AIX, OSF/1 and IRIX, Macintosh System 7, and OpenVMS.

The Galaxy framework components, known as "managers," can be broadly grouped into four categories:

Galaxy abstractions are built on the lowest-available level of native services and provide a single, high-level API across platforms.

Distributed Application Services (DAS) is the part of the Galaxy system that provides communication between any Galaxy applications running on any platform.

DAS is made up of class libraries, run-time services, and tools. In comparing DAS to the well-known OSI protocol model (see Figure 1), DAS encompasses services analogous to the top three layers of the OSI stack. DAS relies on the native-system platforms to provide the services that correspond to the lower four layers of the OSI model. DAS uses an asynchronous, symmetrical, peer-to-peer communications model for efficient, message-based interapplication communication. DAS can be used to implement distributed services in peer-to-peer, client/server, or even master/slave mode. On top of several native protocols, DAS offers higher-level services that facilitate development of distributed applications. DAS also allows Galaxy applications to communicate with non-Galaxy applications, via interapplication communication mechanisms such as the Distributed Computing Environment (DCE). (See "Distributed Computing and the OSF/DCE," by John Bloomer, DDJ, February 1995.)

The DAS model consists of service providers and service consumers. A provider exports a service for use by other applications; a consumer uses such a service. This terminology is preferred over "client/server" because the conventional terms no longer apply to modern distributed-application environments: Increasingly, distributed applications function as both service providers and consumers. For example, every DAS application is a consumer of the services of the DAS Service Broker, the registry service that dynamically locates providers by matching their attributes with those requested by a consumer.

The DAS architecture consists of multiple levels of abstraction to facilitate extensibility and portability; see Figure 2. The design of DAS tries to balance the ease of handling large-grained objects with the flexibility of a large number of API entry points. Objects can be subclassed, modified, and enhanced, and entry points can be added to the API set for specific project needs. The layered abstraction model limits platform dependencies and eliminates interplatform differences in functionality.

DAS managers are in some cases derived from more general-purpose managers. For example, the Datatag Manager is based on the Representation Manager, which, in turn, provides an encapsulation object that transforms data formats between applications on the fly (for example, dealing with floating-point formats on dissimilar platforms) based on the relationships between Galaxy abstract data types and native data types.

DAS Major Components

The object-oriented components comprising DAS include six class managers, a standard dialog called the "Service Chooser," and a run-time service provider called the "Service Broker." The DAS managers consist of the Communication, Datatag, Session, Signature, Service Broker, and Service Managers.

The Communication Manager provides a low-level API to the network. Some applications may use the Communication Manager directly, but most applications will use the higher-level Session Manager instead. The Communication Manager has a transport-oriented view of the network, although it is independent of particular network transports. Applications must implement their own protocols on top of this transport layer, in order to share data across different machine architectures.

The Datatag Manager lets you create and manipulate application data descriptions called "datatags"--a portable description of the structure and contents of a piece of data in your application. Datatags allow application data to be converted to different machine representations and enable transparent sharing of data among applications. The Datatag Manager serves as a bridge between the Representation Manager and the native language (C or C++).

The Session Manager implements high-level abstractions that allow service consumers and providers to communicate with each other without explicit knowledge of the underlying network. A "session" involves two applications communicating with each other, via the vsession abstraction. A session encapsulates the dialog between consumer and provider; see Figure 3. Unlike the Communication Manager, users of the Session Manager do not implement protocols. Derived from the Session Manager, the Session Statement Manager abstracts the requests that one application can make of another. Using the Session Statement Manager, an application forms a "statement" (an encapsulated request) and sends it to a service provider.

The Service Manager is used to define service providers. A "service" is defined as a collection of primitives and attributes. A primitive is a network entry point into the service, abstracted via the Service Primitive Manager (a submodule of the Service Manager). Service consumers use these entry points to make requests of the service. The Service Manager uses the Session Manager for communication between the consumer and the provider.

The Service Broker Manager is used as a high-level interface to the Service Broker from within an application. It provides a set of entry points that can be used by service providers to register their services with the Service Broker run-time service and by service consumers to query the Service Broker for which services are available. The Service Broker Manager uses the Session Manager to communicate between the application and the Service Broker.

The Signature Manager is used as a bridge between statements and primitives. Signatures are primarily used to specify the prototypes for primitives. The statements use these prototypes to help form the actual parameter list with which to invoke the primitives, and to identify the return result (if any). The primitives use these prototypes to identify their arguments and help form the return result (if any). Signatures provide a means for type-checking data sent between service consumers and service providers.

The Service Chooser is a standard Galaxy dialog providing a graphical display of those services that have been registered with a Service Broker. The user can select a service from the Chooser and establish a session with the service without requiring knowledge of the individual attributes of the service. The Service Chooser builds the list of registered service providers by querying the service broker.

A Service Broker is a DAS service that knows about other available DAS services--a networked registry of all registered services. The Service Broker allows providers to register themselves and then maintains lists of their attributes that consumers use in finding a desired service provider. Typically, a network contains many Service Brokers working together, although there is usually only one per machine. This distributed implementation is usually not visible to applications that use the Service Broker.

Unlike a naming service, the Service Broker can match an arbitrary set of attributes between providers and consumers. And, unlike an object request broker (ORB), the Service Broker does not participate in the conversation between the applications. It makes the match and then "gets out of the way," while the applications talk to each other. This model provides greater performance than an ORB implementation, and scales better than a mechanism that is always in the middle of the provider/consumer conversation.

The Datatag Manager

Datatags and signatures are the essential building blocks of interapplication conversations. The Datatag Manager and Signature Manager provide an API that implements object-oriented abstractions for data typing, uniform data representation, and service descriptions. These facilities, which enable transparent interactions between applications across platforms and networks, deserve a closer look, beginning with the Datatag Manager. The Datatag Manager, which is based on the Representation Manager, is used to create and manipulate datatags. Datatags provide a uniform means for specifying argument types, return value types for DAS messages, and allow the efficient conversion of data between the native representation of data and the protocol representation. Datatags are roughly analogous to type definitions in programming languages. They allow applications to share conceptually similar data, even when the physical data representation may differ across a network or a machine architecture. Data descriptions are managed independently of specific uses, except when used in a datatag group.

The Datatag Manager provides functions which return primitive datatags that correspond to common primitive C and C++ types, such as 8-bit signed scalar, double-precision floating point, or strings. The Datatag Manager also provides functions which return datatags that correspond to Galaxy-specific types, such as vbool, vlonglong, or vscrap. The datatag facility can also express how data should be stored, via entities such as the Galaxy dictionary type, pointers, variable-length opaque, and so on. As with type definitions in programming languages, datatags are meant to be shared by all applications using the Datatag Manager.

Also supported are compound datatags, which describe structures that consist of multiple datatypes. Much like the struct construct in C, compound datatags allow you to define a structure that includes diverse types of data, such as pointers, native Galaxy types, linked lists, arrays, dictionaries, trees, and resources. Compound datatags allow complex structures to be handled across the network as efficiently as basic data structures. You can also collect related datatags into a container called a "datatag group." Datatags in a datatag group can be stored, named, and manipulated as resources, and managed as a group.

By using the Representation Manager together with the Datatag Manager, you can encapsulate application data and create a datatag-scrap object. The Datatag Manager defines a base datatag-scrap class and several primitive datatag-scrap classes that provide default conversion behavior for each of the primitive data-tags. Datatag-scrap methods automatically perform the transformations necessary for data to move from application to the network and back. A datatag scrap is typically used as a source or a destination for a call to a function that converts to/from the application data representation. Datatag scraps can be used to convert data stored in foreign representations into the data structures defined by an application.

Using the Datatag Manager

As mentioned earlier, the Datatag Manager can describe and convert data structures defined by an application. Example 1(a) is a structure declared in C. Example 1(b) shows how to convert that structure into a different representation via a scrap.

A linked list is a data structure that can become fairly complex when it contains pointers to other nested structures. Many existing development tools require you to write code that laboriously traverses linked lists, dispatching to the networking software upon each list element. In DAS, datatags have been implemented with pointers that allow linked lists (or other data structures that incorporate references that are noncyclical) to be encapsulated and passed across the network without the explicit involvement of the programmer. Example 2(a) declares a linked list using a C struct. Example 2(b) shows the equivalent datatag description. Example 3(a) and 3(b) show how the datatag can be used by a provider or consumer to send/receive the linked list across machine architectures without laborious conversion code.

Datatag scraps can be used in concert with the Resource Manager to share complex items between applications running on the network. The Resource Manager is "scrap aware," so anything that can be stored as a resource can be accessed as a scrap. This includes dialog windows, user-interface objects, text, error messages, color images, internationalization and geometry-management information, or other structured data. The steps in transmitting resources over the network are:

  1. Store an item as a resource.
  2. Use the Resource Manager API to make a scrap from the resource.
  3. Send the scrap with the predefined scrap (vdatatagGetScrap()).
  4. Receive the scrap.
  5. Convert the scrap back into a resource.
  6. Load the item from the resource.
As an example, say that several applications on different platforms need to share a background-color specification. On each platform, burnt sienna may be defined differently. How do you define a color specification that can be used across these platforms? In Galaxy, there is a platform-independent color-specification abstraction. This abstraction can be made into a resource, which in turn can be made into a scrap, which in turn can be used with DAS to provide a color specification as a run-time service. Example 4(a) shows the service-consumer side of requesting a color spec, while Example 4(b) shows the service-provider side.

Examining the Signature Manager

The Signature Manager is used to create and manipulate descriptions of primitives known as "signatures," roughly analogous to function prototypes in C and C++. A DAS primitive is a service entry point that is callable by consumers. The primitive's arguments and return type are described with a signature. Example 5 shows how to assemble datatag objects into a signature when the primitive has a large number of arguments.

Signatures provide a bridge between DAS statements and DAS primitives. Statements use the signature as a prototype in forming the parameter list when invoking the primitive, and in identifying the return result. Primitives use the signature in identifying their arguments and in forming the return result. Arguments and results are typed via datatags created by the Datatag Manager.

Signatures are typically stored in Galaxy resource files, so they can be shared by developers and, at run time, by service consumers and providers. In addition to being stored as resources, signatures can be created at run time through API calls. This allows an application to deal with data whose structure is not known at compile time.

Services and Sessions

The Service Manager provides abstractions for creating and managing service pro-viders. As mentioned earlier, a service consists of primitives and attributes. Primitives are entry points into a service, and are invoked when a consumer sends a statement to the service. Attributes describe the service and how it can be located and used by a consumer. Attributes take the form: {name, type, value}. Each attribute is uniquely named and is typed via a datatag. A service can have any number of attributes, and you can add attributes to a service so that its functionality becomes easier to identify by potential consumers.

For a provider to participate in sessions with new consumers, it must be explicitly exported and enabled. Only enabled services can register themselves with the Service Broker. A nonregistered service can only be accessed by consumers that have been hard-wired to directly talk to the specific service.

Service consumers initiate conversations, or "sessions," with service providers. The Service Manager creates a new session each time a service is invoked, one session for each connection with a consumer. A session is represented by the datatype vsession. Every consumer/provider connection consists of two vsession instances, one of which is private to the consumer and one of which is private to the provider. The consumer uses its vsession to send statements to the provider; the provider, likewise, sends return results and status information via its vsession. In true peer-to-peer DAS sessions, both vsessions are capable of querying and providing return results.

DAS supports fully asynchronous communications between service providers and service consumers. An application can be a consumer of multiple providers concurrently, and can have multiple statements (encapsulated requests) pending with one or more providers, while continuing to process other DAS, GUI, or OS events from the Galaxy event loop. Alternatively, DAS supports synchronous interactions--for situations where the application must wait for results from one operation before proceeding with other threads of execution.

Many existing development tools only allow network applications to interact based on hard-coded locations or hard-coded server IDs. By contrast, the DAS Service Broker allows applications to interact at run time based on the attributes they have registered with the Service Broker. For example, if the user needs a text editor, the application queries the Service Broker for available text editors and can, based on the attributes of the request, match anything from a WYSIWYG word processor to a programmer's editor. You don't have to specify the editor by specific name or network ID. It is possible for a service to be selected by a consumer based on only one or two of the many primitive functions it might have to offer.

Applications establish sessions with the Service Broker by creating a vsession and setting the appropriate attributes. Any vsession can be used to establish a session with the Service Broker. The appropriate attributes would be contained in the scrap returned by vdasservCreateAttributeScrap. Example 6 shows how an application establishes a session with a Service Broker by hand. If you use the vdasservRegister-Service and vdasservUnregisterService functions, you don't have to establish a session explicitly.

An application can find available service providers by sending the Service Broker the statement returned by vdasservMakeMatchStatement. The statement takes two arguments: a vsession (with a broker), and a dictionary scrap that specifies some of the required attributes and their values. An array of providers that match the attributes is returned. Any provider matches the request if it has all the attributes in the specification scrap with appropriate values. The resulting array is not ordered and may contain providers that were registered on other service brokers known to the service broker that handled the request. Example 7 shows how to locate all of the services known to a service provider.

Conclusion

The DAS facility in Galaxy provides an infrastructure of abstractions for building platform-independent distributed applications. This facility has been field proven through extensive use in large-scale, complex applications across a broad range of industries.

For More Information

Galaxy 2.0

Visix Software

11440 Commerce Park Drive

Reston, VA 22091

703-758-8230

Figure 1 DAS facilities are analogous to the top three layers of the OSI protocol stack. Figure 2 An architecture of DAS allows access at various levels of abstraction. Figure 3 The service-provider/service-consumer model.

Example 1: (a) Application data structure to be converted; (b) converting an application data structure into a different data representation.

(a) typedef struct myStruct myStruct;
    struct myStruct
    {
        short         first;
        vlonglong     second;
        double        third;
        vfixed        fourth;
    };

(b) vscrap * myCreateStructScrap (myStruct *ptr)
    {
        vdatatag *dtag;
        vscrap *scrap;
        dtag = vdatatagCreateCompound();
        vdatatagConstructCompound(dtag,
                vdatatagGetShort(),
                vdatatagGetLonglong(),
                vdatatagGetDoubleFloat(),
                vdatatagGetFixed(),
                NULL);
        scrap = vdatatagScrapFromValue(dtag, ptr);
        return (scrap);
    }

Example 2: (a) A linked list expressed as a C struct; (b) a linked list described using datatags.

(a)

typedef struct barney barney;
struct barney
{
      unsigned int     purple;
      float            dinosaur;
      vfixed           beast;
      barney           *next;
};
barney *listTop;

(b)

ptr  = vdatatagCreatePointer();
dtag = vdatatagcreateCompound();
vdatatagConstructCompound(dtag,

vdatatagGetUnsignedInteger(),
      vdatatagGetSingleFloat(),
      vdatatagGetFixed(),
      ptr,
      NULL);
vdatatagSetPointerDatatag
                     (ptr, dtag);

Example 3: Using the datatag to describe the linked list: (a) as a service consumer; (b) as a service provider.

(a)

vsessionSetStatementArgs(session,
                        listTop);

(b)

vserviceGetPrimitiveArgs(prim,
              scrap, &listTop);

Example 4: Requested as a network service, a color specification has been converted to a resource and then encapsulated as a scrap; (a) the service-consumer side; (b) the service-provider side.

(a)
vcolorspec *colorspec;
vresource res;
vscrap *scrap;

res = vresourceCreateMem();
vcolorStoreSpec(spec, res);
scrap = vresourceGetScrap(res, NULL);

/* signature for statement has vdatatagGetScrap()
 * as argument datatag */
vsessionSetStatementArgs(session, scrap);

vscrapDestroy(scrap);
vresourceDestroyMem(res);

(b)
vresource res, one;
vcolorSpec *spec;
vscrap *scrap;

/* signature for primitive has vdatatagGetScrap()
 * as argument datatag  */
vserviceGetPrimitiveArgs(prim, args, &scrap);

res = vresourceCreateMem();
one = vresourceCreate(res, vname_Foo, vresourceUNTYPED);
vresourceSetScrap(one, NULL, scrap);
spec = vcolorLoadSpec(one);

vscrapDestroy(scrap);
vresourceDestroyMem(res)

Example 5: Datatag objects are used to construct a signature for a primitive.

{
  vsignature sig;
  vsignatureCreate();
  vsignatureSetTag(sig, vnameInterGlobalLiteral("my primitive"));
  vsignatureSetReturnDatatag(sig, vdatatagGetInteger());
  vsignatureConstructArgs(sig, vdatatagGetShort(),
          vdatatagGetFixed(),
          vdatatagGetLongLong(),
          vdatatagGetString(),
          vdatatagGetInteger(),
          NULL);
}

Example 6: Establishing a session with a Service Broker.

{
   vsession    *sessionBroker;
   sessionBroker = vsessionCreate();
   vsessionSetAtrributesFromScrap(sessionBroker,
                        vdasserCreateAttributeScrap());
   vsessionBegin(sessionBroker);
   ...
   vsessionEnd(sessionBroker);
}

Example 7: Locating services known to a Service Broker.

{
    vsessionStatement        *statement;
    vsession                 *sessionBroker;
    vscrap                   *scrapSpec;

    // initialize sessionBroker

    scrapSpec = vscrapCreateDictionary();
    statement = vdasservMakeMatchStatement(sessionBroker, scrapSpec);
    vessionSetStatementNotify(statement, exampleMatchNotify);
    vessionSendStatement(statement);
    ...
}


Copyright © 1995, Dr. Dobb's Journal

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.