Categories
Computing Mac OS X PHP Web Development

Enabling Oracle OCI8 PHP Extension on OS X Snow Leopard

My current project involves using PHP with an Oracle database. Oracle apparently embraces PHP warmly and as such supports an open source database driver for the environment called OCI8. As a Mac user I was looking to use OS X's built-in Apache and PHP setup, which like many PHP installations does not have the Oracle OCI8 driver installed or enabled. It took me some time and research to get it up and running. I was using Oracle Express, a limited capability, free-ish version of Oracle's database. Oracle Express was installed on a separate Windows machine as it cannot run or be installed on Snow Leopard. I also assume that you enabled PHP in your Apache configuration (/etc/apache2/httpd.conf) and have a /etc/php.ini by copying it from /etc/php.ini.default.

OCI8 relies on OS X having several client libraries and tools from Oracle installed on OS X. For most intents and purposes download the 64-bit version of the following files under the title "Version 10.2.0.4 (64-bit)": 

Registration is required for all downloads.

Share
Categories
Java

Odd behavior using Apache Commons Pool

I am trying to use an object pool. The idea is to reuse objects that require resources or time during their creation and that can easily be reset after each use. The classic example is a network connection pool, and the Apache Commons Database Connection Pool (DBCP) is the prime example and user of its sister project, Apache Commons Pool. DBCP is in very wide use and as such I felt is a good reason to rely on Commons Pool in my code. And like DBCP, I am using Commons Pool to manage connections, XMPP connections in my case.

Like a good object pool, Commons Pool relies on an Object Factory which is supposed to manage the lifecycle of the pooled objects. The factory, PoolableObjectFactory, has all the methods you would expect

  • instantiating pooled objects
  • activating objects when being ‘borrowed’ from the pool, taking back resources if necessary
  • validating objects – is the object ok for use? are all the resources successfully regained
  • passivating – releasing resources when the object is not in use, after it is ‘returned’
  • destruction – no need to keep too many objects around if no one is using them

My test case involves the use of an XMPP message source, sending messages every 50 milliseconds or less, and an XMPP message reader, which reads the message and replies to the source.

The reader runs on an infinite loop (e.g. for ( ; ; ) ) while the source sends the messages and then loops infinitely waiting for the responses. Since the sender sends the messages rapidly but in serial fashion, one XMPP connection was necessary, but the reader – which is supposed to do work on the messages, I wanted to use the pool. The sender sends 50 messages and as mentioned, waits, using built-in functionality in the XMPP client library I am using, Smack.

The final bit of information necessary to understand what I experienced is that to implement the pool I am using Commons Pool’s built-in GenericObjectPool with a setting telling it to block requests when all of the pool’s objects are in use. In order to avoid absolute lockups, I also set the pool up to time out after 10 seconds. More importantly, the pool is set up to have at least 2 objects, up to 5 objects if necessary, and to leave 4 idle if they are already created. These are all cool and pretty useful settings afforded to me by GenericObjectPool.

It appears that while the reader currently does nothing else but a one-line manipulation of the incoming message, I am reaching that timeout when no objects are available. The way my code initially worked was:

  • Poll the XMPP queue for messages. If none arrived, sleep for 150 milliseconds.
  • If a message arrived, borrow a connection from the pool
  • Process the message
  • Send response using connection
  • Return the connection to the pool

Apparently this caused this supposed deadlocking or timeout. While it is a single thread that sleeps, and I hope resumes when it wakes up, I kept getting exceptions pertaining to the timeout.

My current ‘solution’ reduces the borrow-object return-object time to the bear minimum, where the aforementioned workflow is now (changes underlined):

  • Poll the XMPP queue for messages. If none arrived, sleep for 150 milliseconds.
  • If a message arrived, process the message
  • Borrow a connection from the pool
  • Send response using connection
  • Return the connection to the pool

What is interesting to me is why the unused connection, which I *did* return to the pool, were not being reused and thus caused the timeout. My code is not even remotely great. The ‘solution’ mentioned above is but an empirical result with a mild shot of rationalization. Hope it keeps working.

Share
Share