Dimeric Software logo

Rinse

Overview

Rinse is to Delphi as RMI is to Java -- in other words, Rinse is a remote method call architecture (similar to DCOM, SOAP, CORBA, etc.) that is specifically designed to work with Delphi's type system. The most frustrating thing about using other distributed application frameworks is that they require you to "dumb down" your interfaces. You cannot take advantage of the rich type system offered by Delphi. This has many negative implications on software development.

With Rinse, you can develop distributed applications that make full use of Delphi's type system. You can use objects (via interfaces), arrays (static, dynamic, and open), sets, enumerations, sub-ranges, records, and variants (including variant arrays) in your distributed applications. Rinse offers a host of other features -- for more information, see the Rinse Feature List.

Advantages

Rinse offers superior code reuse, because Rinse services can be used by any of the following types of consumers: 2-tier applications, 3-tier clients, 3-tier servers, and web applications. Furthermore, Rinse services use the ideal parameter types for the task at hand.

Rinse features an extensible, layered architecture, making it easy to add new functionality to the communication framework. Rinse supports TCP/IP and HTTP protocols, and additional protocols may be defined. Also, various features, such as encryption, compression, session management, etc., can be implemented as separate layers. In total, Rinse comes with 11 transport layers. The full version of Rinse includes complete source code for these layers, along with the rest of the library code that is compiled into your client and/or server applications.

One of the most attractive features of Rinse is its automatic context management. For each request from a client, Rinse manages a context object that holds transactional resources such as database connections. If the server method completes normally, Rinse will automatically commit any objects in the context. However, if an exception is being returned to the client, then Rinse will roll back any objects in the context. In a nutshell, this allows you to implement your server-side methods without coding the tedious exception-handling block in every method. For example, in DCOM, you might see...

procedure TRemoteDataMod.DeleteAllOrders;
begin
  Database.StartTransaction;
  try
    Database.ExecSQL('delete from order_detail');
    Database.ExecSQL('delete from cust_order');
    Database.Commit;
  except
    Database.Rollback;
    raise;
  end;
end;
However, with Rinse, the exception-handling block is implemented automatically. So, the above example would become...
procedure TRemoteDataMod.DeleteAllOrders;
begin
  Database.ExecSQL('delete from order_detail');
  Database.ExecSQL('delete from cust_order');
end;
Of course, sometimes you want to roll back the transaction without raising an exception. Also, it is sometimes handy to be able to raise an exception yet still commit the transaction. In these cases, you may simply call the SetRollback or IgnoreExceptions methods of the context object. In practice, the vast majority of server methods do not need to worry about the context. Just go to the database, run your queries, and Rinse takes care of the rest!

Rinse has already been used to build a dozen production applications -- including this very website! We defined a handful of Rinse services to take care of the database access, credit card processing, etc. This keeps the web pages (DSP pages) clean, and isolates the business logic from the presentation. Down the road, we could easily split these into two separate physical tiers, but for now they both reside in a single process (the web server application).

Download Rinse

You can download a fully-functional trial version of Rinse.

On-Line Resources

You can learn more about Rinse online in the following documents, which are also included in the trial and full versions.

  • The Rinse Tutorial is a good step-by-step introduction to programming in Rinse. Each step builds on previous steps, to create fully functional client and server projects that illustrate the functionality of Rinse.
  • The Rinse Introduction is a good reference guide that discusses the various features of Rinse. It is more detailed than the Rinse Tutorial, but does not provide any examples of complete Rinse projects.

Sizing Up the Competition

Because Rinse is designed to work with the Delphi type system, it offers many features missing from most other middleware frameworks. The highlights include:

  • Polymorphism - Surprisingly, many remote object technologies do not support polymorphism. For example, Rinse allows you to declare a remote method GetEmployee that returns an IEmployee object. When this method is called, it may return an IEmployee object or any inherited type, such as IManager or IConsultant. Of course, Rinse also supports heterogeneous collections. For example, consider a remote method that passes an array of some base type. The array may actually contain elements of various types, as long as each is derived from the base type. Naturally, Rinse supports polymorphism for function resuts and for all parameters (input, output, and in/out parameters). In many other remote object frameworks, polymorphism is not supported, and as objects are passed between processes, they are "truncated" to the declared type. Polymorphism is a fundamental concept of Object-Oriented Programming, so its omission from a remote object framework is severly limiting.

  • Object Networks - A network of objects is a collection of objects that refer to one another. Examples include binary trees, linked lists, and graphs in general. A more concrete example would be a Customer object that includes Order objects for the customer. Rinse transmits networks of objects intact. Specifically, if the same object is referenced more than once in an object network, Rinse detects this and ensures that the network is reconstructed faithfully on the recieving end. For example, imagine a remote method that returns a collection of Departments, each Department containing the Employees who work in that Department. If a given Employee works in multiple Departments, then the same Employee object would be referenced by multiple Departments. When this data structure is returned from the remote method, Rinse streams the Department and Employee objects over the network, but it also detects duplicate Employees. Of course, Rinse avoids writing the same object twice, but instead writes a special reference so that the recieiving process knows to re-use a previously sent object. While this may be complicated to explain, it works automatically, helping to ensure that remote methods work as much like regular methods as possible.

  • Typed Exceptions - Most remote object frameworks do not support typed exceptions. Typically, they turn any exception raised on the server into a simple exception that only has an error description (just a string). However, Rinse allows you to transmit any type of exception from the server to the client (you just need to register your exception with the streaming system). Also, Delphi's standard exception types (EAbort, EOverflow, EListError, EStreamError, etc.) are all supported automatically.

  • Method Overloading - Simply use the overload keyword as you nomally would when defining methods.

  • Parameter Passing Modes - Rine supports all four of Delphi's parameter passing modes: pass-by-value, pass-by-reference (i.e., the var keyword), constant reference (i.e., the const keyword), and output (i.e., the out keyword). These four modes determine the direction of information flow. For example, a parameter with the const keyword (or no keyword at all) is an input parameter, so Rinse sends data from the client to the server. A parameter with the var keyword is an input/output parameter, so Rinse passes data from the client to the server, and then back again when the method finishes. Finally, a parameter with the out keyword is an output parameter, so Rinse sends nothing from the client to the server, but does send a value in the opposite direction when the method finishes.

  • Warning Directives - Rinse supports Delphi's warning directives: library, platform, and deprecated. Just use these keywords as you normally would when defining a method, type, or constant.

  • Calling Conventions - Rinse supports all of Delphi's method calling conventions: register, stdcall, safecall, pascal, and cdecl. Of course, the default is register, but if for some reason you want one of the others, just use the appropriate keyword as you normally would.
The common theme in the above list is that Rinse attempts to make remote methods work like normal methods (as much as possible, anyway). This is very important because developers don't have to learn two different sets of rules, and constantly shift from one to the other. It also allows applications to be migrated to a distributed architecture more easily. Finally, Rinse fully supports OOP principles (encapsulation, inheritance, polymorphism, exceptions, etc.), allowing developers to design their distributed applications in a familiar, object-oriented fashion.

   Privacy Policy © 2002 Dimeric LLC. All Rights Reserved. Contact Us   
> Powered by VDB, DSP and Rinse <