Ice is a distributed computing platform that was created by industry veterans with many years of experience. Its features are the result of extensive in-the-field application development, both by ZeroC staff and many of ZeroC's customers, so Ice's features reflect the needs of real-world applications with real-world problems: if Ice provides a particular feature, the feature exists because real applications needed it.
Yet, despite its very rich feature set, Ice strictly adheres to the "you don't pay for what you don't use" philosophy. ZeroC has taken great care not to burden developers with a steep learning curve, complex APIs, or impenetrably complex configuration: simple things are simple, and only complex things are complex.
This design philosophy makes it easy to use Ice and be productive almost immediately. More complex features, that typically are required as an application evolves, can be learned incrementally as the need for them arises. Features that are not needed by a particular application stay out of the developers' hair and do not negatively impact productivity.
The following is a brief summary of noteworthy features of Ice. This list is far from complete; for more detailed information, please consult the Ice Manual and Slice Reference in our Documentation Center.
Operating Systems and Programming Languages
Modern and Flexible Interface Definition Language
Slice (Specification Language for Ice) provides a rich set of data types that cleanly map to all supported languages. User-defined types include enumerations, structures, sequences, and dictionaries, as well as classes and exceptions with inheritance. Classes support pointer semantics, so arbitrarily complex graphs of objects (including cyclic graphs) can be passed over the wire.
Run-time polymorphism is preserved across address space boundaries, so a more-derived type can always be substituted where a base type is expected.
Reopenable modules and support for separate compilation prevent trivial changes to one part of a system from forcing recompilation of the entire system.
Easy-To-Use Language Mappings
Ice provides languages mappings that integrate naturally and elegantly with the features of each language and its libraries. For example, Slice dictionaries naturally map to C++ maps, Java maps, and .NET dictionaries, so programmers can use language constructs that they are already familiar with. Language mappings are type-safe, thread-safe, and exception-safe, and so prevent many bugs from ever making it into the code base. For C++, Ice has rock-solid and fully automatic memory management that makes it impossible to leak or corrupt memory.
- Synchronous and Asynchronous Invocation and Dispatch
Ice supports both synchronous (blocking) and asynchronous (non-blocking) invocations. Asychronous invocations allow the caller to regain the thread of control while an RPC is in progress in the server and to be asynchronously notified of the result of the RPC when it completes.
For the server side, Ice provides both synchronous and asynchronous dispatch. Asynchronous dispatch permits a server to service an arbitrary number of concurrent requests from clients without tying up a processing thread for each request.
- Dynamic Invocation and Dispatch
Besides static invocation and dispatch, which rely on compiled Slice definitions, Ice supports dynamic invocation and dispatch, which delay the decision as to which types are used for communication until run time. This feature permits you to create applications (such as routers and protocol bridges) that must deal with Slice types that are unknown at compile time.
- Oneway, Datagram, and Batched Invocation
Ice supports oneway (for TCP and SSL) and datagram (for UDP) invocations. The server does not return a reply for such invocations, so clients can use it to implement "fire and forget" semantics.
Oneway and datagram invocations can be batched: instead of sending a separate message over the network for each invocation, batched invocations are buffered in the client-side run time and, once the client decides to transmit a batch, are transmitted to the server in a single network message. Batched invocations are more efficient, in particular, if a client needs to invoke a number of "set" operations that transmit (but not return) data.
- Request Forwarding
Ice permits applications to receive a request as an opaque blob of data (known as a blobject) and to forward the request to a new destination. This enables the creation of very efficient message routers, such as IceStorm or Glacier2, because messages can be forwarded without the need to unmarshal and remarshal data.
The Ice run time is fully threaded and fully thread-safe. You never need to acquire critical regions in order to protect data structures in the run time; the only critical regions are those that you require to protect application-specific data from race conditions.
Ice permits sophisticated control over how the run time uses threads. You can allocate and control the size of several thread pools to separate concerns and ensure that activity in one part of the system cannot consume threads that must remain available for a different part of the system.
Ice provides a portable threading library for C++ that makes it easy to create threaded applications that are source code compatible with Linux and Windows.
You can choose among TCP, SSL, and UDP as a transport for invocations. Ice supports both IPv4 and IPv6. Connection management is completely transparent: the Ice run time opens and closes connections as needed. However, you can also control connection establishment explicitly, for example, to reserve a separate connection for specific invocations. A single server can make its services available via several transports simultaneously, and clients can freely use objects that are implemented in servers using different transports.
The Ice protocol uses a compact binary encoding that conserves bandwidth and is very efficient to marshal and unmarshal. For bandwidth-limited communication (such as over satellite channels), Ice provides protocol compression, which reduces the size of invocations to the absolute minimum. Compression can be enabled and disabled at run time and requires no code changes.
Once a distributed system is deployed, it requires maintenance to accomodate bug fixes and improvements. With conventional technologies, it is difficult to do this because changes to interfaces or data types break the existing on-the-wire contract between client and server, forcing all components of a system to be upgraded at once.
Ice provides two solutions for dealing with this problem. Using optional values, data members and operation parameters can be added and removed without breaking the on-the-wire contract. With facets, you can add new features or change existing features in an elegant and non-intrusive way. You can easily make changes such that they remain backward compatible and, therefore, upgrade a distributed system gradually.