Globus Toolkit 3.9.5: Best Practices for Developing in GT4
This page provides some recommendations for developing with the Globus Toolkit 3.9.5 and its components.
Implementing Services
- Dynamic resource creation and the factory pattern
- Scalability, recovery and resource persistence
- Concurrent invocations and synchronization
- Lease-based lifetime management
- Messaging granularity
- Choosing an authentication mechanism
Dynamic resource creation and the factory pattern
OGSI defined a standard create method for creating new grid services. The follow on, the WS Resource Framework, no longer defines such a mechanism. This does not mean that the factory pattern is not valuable. Rather, it was removed because any non-trivial create method tends to be application specific, a observation that leads to the conclusion that there is little value in standardizing this operation. We recommend the use of the factory pattern for dynamic creation of resources. In particular we recommend writing a factory service that provides a way to create new resources and allows users to inspect state information about the aggregation of all resources created by the factory service, e.g. the number of resources managed. In addition to the factory service one would write a service that interacts with the resource instances created by the factory service.
Scalability, recovery and resource persistence
Writing scalable (in the number of resources) and recoverable, i.e. give it the ability to survive a server crash and restart, resources takes a bit of careful planning. There are several potential pitfalls:
- Since scalability relies on using Java soft references it is important that resource do not keep hard references to any objects that would prevent the soft reference mechanism from working.
- When recovering resources after a container restart it is often important to re-establish the current state of the process the resource represents, e.g. if the resource is monitoring a external entity via notifications it should query for the current state of the external entity upon restart.
- Persisted resources need to be carefully written to avoid the following problem: If a service currently holds a hard reference to the resource, the resource is destroyed (i.e. the soft reference to the resource is removed from the resource home and the resource is removed from persistent storage) after which the service holding the resource reference can still cause a call to the store persistence callback, which me restore the persisted copy of the resource.
- Resource implementers need to be carefull when storing complex types created by axis as part of the web service operation invocation. These complex types have references to sizable objects associated with the Axis deserialization/data-binding process. TODO: explain how to work around this.
Concurrent invocations and synchronization
The container does not provide automatic synchronization of concurrent requests. This means that service implementors need to write their services to deal with potential synchronization problems. If you service itself is stateless this means that if you will need to synchronize around access to the state captured in the resource. That being said, in a lot of scenarios you can expect a single client to drive most interactions with a given resource, in which case synchronization may not be an issue.
Lease-based lifetime management
We recommend that you make use of lease based resource lifetime management to avoid orphaned resources due to network outage and other failures. Lease based lifetime management is accomplished by specifying a initial lifetime in the resource creation operation followed by periodic updates to the lifetime using the setTerminationTime operation specified in the WS Resource Lifetime specification.
Messaging granularity
Our current performance profile for the Java WS Core component currently only allows for fairly coarse grained operations at a reasonable level of performance. While this statement is in relation to Java WS Core performance it is in reality relevant to any distributed applications: Remote invocations always cost more than local invocation (give infinite CPU power/memory) and should thus be treated differently than local invocations.
Choosing an authentication mechanism
GT4 provides a implementer with a choice of 4 authentication mechanisms: HTTPS (ie SSL/TLS), WS-Security with X.509 certificates, WS-Security Username/Password authentication and a GSSAPI based WS-Trust/SecureConversation/Security based mechanism. We recommend that service implementors try to support the greatest number of mechanisms possible. Generally, services that need both authentication and message protection should always allow any mechanism other than the username/password one.
The story is somewhat different on the client end of things. Whereas server side security configuration is mostly policy driven, clients actually have to pick a specific mechanism to implement. We recommend that clients use HTTPS whenever available, i.e. whenever the service URL indicates a HTTPS transport, but are able to fall back on WS-Security with X.509 certificates should the transport be a non-https one. This recommendation is based upon performance comparisons of HTTPS vs. WS-Security based mechanisms, which have shown HTTPS to be much higher performance, especially as the message payload grows.