Tuesday, June 21, 2011

JBoss Drools in a warehouse management system..

So the last year I've been working on an application at work that serves as a module of our warehouse management system. The short version of the problem description is that we were automating the process by which fork lift drivers figured out what pallets needed to be lowered from the storage location up in the racks down to the pick bin (floor level) where the order selectors grab the cases when filling an order. The previous process relied upon the lift drivers to just know when a bin needed to be replenished, and if a bin was empty, the order selector had to find the lift driver and yell to them that bin XYZ needed to be replenished. Not terribly efficient...

The application we built to solve this problem runs on top of Jboss 5 and PostgreSQL 8.4, uses JPA, Jboss Drools, EJB, and JMS. Our first version actually used JBPM as well, but we went away from that as it wasn't a good fit for what we needed. We also started with GWT on the front end but ditched that a few months into the project in favor of Grails + Jquery.

To make all this happen we had to integrate with our legacy COBOL homegrown WMS and several different pieces of the voice picking system used by the order selectors. Obviously all the data is coming from the COBOL wms system, but we added hooks into the voice picking system so the selectors could both "call in" a replenishment if the bin was empty, and hear when the bin they called in was replenished.

The early versions made decisions of what task to give a replenisher (fork lift driver) based almost completely on the number of cases in the bin. The only other variables were what region he was authorized to work in and his last known location, which we used to try to give him a replenishment task to do that was close to him. We have added more and more data to those calculations, which have become pretty significant.

The calculations of what the priority of the replenishment tasks are, and the calculations for which of the tasks someone should actually do are all done using Drools. I had never used a rules engine before this project, and it took a little time to get the hang of it, but I have to say now, I really enjoy using Drools! Our last major change included shifting the priority calculation from stateless rules sessions to a stateful rules session, which brought on another whole set of challenges. The task priorities are now set using not just the number of cases in the bin, but also all the various kinds of demand information in the system and how far along they are in their life-cycle. By demand information I mean orders that are being worked on currently by selectors, orders that haven't been processed yet, etc. The task dispensing logic is still done using stateless rules sessions, but includes logic for special situations, what to do in the event of a tie between the score of two tasks, etc in addition to the proximity logic.

I could go on and on about lessons learned along the way, which I plan on doing in upcoming posts... There are things with jvm turning, jms features, drools features, etc that I think would be useful for others developing applications.