I now have a functioning RabbitMQ Library! Though, there is a lot more to be done to make it satisfactory.
There are two problems:
- Missing the Queue Consumer functionality. This makes it a lot easier to deal with RabbitMQ so I definitely want to get this in.
- I’m not happy with using the record type to capture the Read and Publish functions for a queue. After all, how often are you going to be writing to and reading from a specific queue in the same process?
I will start by fixing #2, as that is bothering me the most. The design, at present, has this flow:
- Connect to a RabbitMQ server
- Open a channel
- Request a connection to a queue
- Receive a function for writing to the queue and a function for reading from the queue
The first question I have is: how often are you going to be reading from and writing to the same queue in the same code? Probably not very often. Which means that, most of the time, only half of what I am returning is useful. We can simplify this. Rather than build the Read and Write functions for you, they should be built only when you need them.
I will change the design so that rather than opening a queue and getting back two functions. There will be two functions which can write or read to any queue.
My next design approach will be to update the function which creates a channel to now also return two functions: one function will be for using the channel to write to a queue, the function is for using the channel to read from a queue. Now if you want to setup a publishing function to “MyQueue” you use the returned write function and partial application to build the writeToMyQueue function.
I’ve modified my readFromQueue function so that it now takes a channel and a queue name and returns a function which will read one message from the queue:
1 2 3 4 5 6 7 8 9 10 11
Then I made this new function:
Which will take a channel and return two functions. One for writing to a specific queue and one for reading from a specific queue. You can then use these two functions to connect to queues as you need. Once a developer reaches this point, all he or she needs to think about are: queue names, do I want to read from this queue, and do I want to write to this queue.
For example, in my receiver the code is now:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
I don’t care about writing to queues at all, so I completely ignore the write function which createQueueFunctions returns.
The Sender code now looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
I find that this design is a lot better. Functions for reading and writing are only created when you need to read or write to a queue. The channel object can now safely be ignored after the initial setup, instead everything boils down to: what do I want to do with this queue. When you write with this framework, you now are no longer concerned with what objects you have at hand and what you can do with those objects; you are just concerned with what you want to do.
The complete source as of this point:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51