OCI*ML new feature: AQ

Many organizations make heavy use of message-oriented middleware, such as Oracle AQ. An interesting thing about message buses is that so long as a program can participate in the sending and receiving of messages it doesn’t matter what language it is written in, so I have added the capability to interoperate with AQ to OCI*ML. This proved to be quite tricky, as to get the very high-level interface to it I wanted, I am effectively generating new object-types on the fly, something I don’t think the underlying OCI was really designed for.

On with the code! First, to create an AQ:

create type message_t as object (
       message_id     integer,
       message_text   varchar2(80));
/

begin
	dbms_aqadm.create_queue_table (
		queue_table => 'tbl_message_queue',
		queue_payload_type => 'message_t');
				  
	dbms_aqadm.create_queue (
		queue_name => 'message_queue',
		queue_table => 'tbl_message_queue');

	dbms_aqadm.start_queue (
		queue_name => 'message_queue');
end;
/

This declares a new type message_t, sets up a table of the type and creates and starts a queue on it. The type definition will be needed to write OCaml to interact correctly with this particular queue. To enqueue a message:

$ ./ocimlsh
# open Ociml;;
# let lda = oralogon "gaius/abc123";;
# oraenqueue lda "message_queue" "message_t" [|Integer 99; Varchar "hello, world!"|];;
# oracommit lda;;

Note the commit, as this is an Oracle product it works just like a database, similarly when dequeueing one must also commit to confirm receipt of the message. I am specifying the name of the queue, the type of the queue, and an array of OCI*ML types comprising the message body, which matches message_t declared in the PL/SQL. This can obviously be curried, so only the message needs to be applied. Dequeuing is similar, but requires a “dummy” message so that OCI*ML is able to convert the types it gets back from Oracle correctly:

# oradequeue lda "message_queue" "message_t" [|Integer 0; Varchar ""|];;
- : Ociml.col_value array = [|Integer 99; Varchar "hello, world!"|]
# oracommit;;

In both cases, significantly less code that it would take to do this in PL/SQL in SQL*Plus.

Performance seems reasonable; using Tibco’s assumption of 50-byte message, I can enqueue/commit at a rate ~100 msgs/sec on a very small system (a 1G Debian VM running XE) , spending ~92% of time waiting on Oracle†, so OCI*ML itself is nowhere close to being the bottleneck, despite no optimization (such as caching the TDO, or native compiling with ocamlopt) and I would expect this to fly on real hardware.

While I won’t be building a trading engine on OCI*ML quite yet, this is perfectly serviceable for reliable, asynchronous notification and IPC for distributed systems and over WAN links. Next up will be support for more datatypes, particularly Raw. Perhaps after all these years, as an administrator of rather than having a use for it myself, I might reconsider my opinion of AQ…

† Which in turn is spending most of its time on log file sync wait to a slow virtual disk, and autocommit is not supported for AQ so there is additional latency even over a local connection.

About Gaius

Jus' a good ol' boy, never meanin' no harm
This entry was posted in Ocaml, OCIML, Oracle. Bookmark the permalink.

7 Responses to OCI*ML new feature: AQ

  1. Pingback: OCI*ML: Minor updates | So I decided to take my work back underground

  2. Pingback: OCI*ML: Support for RETURNING | So I decided to take my work back underground

  3. Pingback: OCI*ML: Ref Cursors and Raw Messages | So I decided to take my work back underground

  4. Pingback: OCaml bindings for Coherence with SWIG | So I decided to take my work back underground

  5. Pingback: OCaml binding for Coherence MapListener | So I decided to take my work back underground

  6. Pingback: Custom classes in Coherence with OCaml | So I decided to take my work back underground

  7. Pingback: Putting it all together: PubSub for OCaml with Coherence | So I decided to take my work back underground

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s