0

At a high level, what I need to do is have a python script that does a few things based on the commands it receives from various applications. At this stage, it's not clear what the application may be. It could be another python program, a MATLAB application, or a LAMP configuration. The commands will be sent rarely, something like a few times every hour.

The problem is - What is the best way for my python script to receive these commands, and indicate to these applications that it has received them?

Right now, what I'm trying to do is have a simple .txt file. The application(s) will write commands to the file. The python script will read it, do its thing, and remove the command from the file.

I didn't like this approach for 2 reasons- 1) What happens if the file is being written/read by python and a new command is sent by an application? 2) This is a complicated approach which does not lead to anything robust and significant.

sbhatla
  • 1,040
  • 2
  • 22
  • 34

2 Answers2

2

Integration patterns

There are few integration patterns usable for this purpose.

Messaging allows decoupling by communicating contracted messages, all the rest is left as platform specific detail, which does not affect other parties.

Other method could be e.g. shared data store - one side would store requests for processing there, another would fetch them and process.

Messaging integration pattern using ZeroMQ

ZeroMQ is a library, allowing very lightway messaging without requiring to run some big messaging application.

What you describe could be resolved this way:

  • Python script is running in a loop, awaiting requests for something to do.
  • Any client (being able to issue ZeroMQ request) would ask for an action and get the response

With clients being in multiple languages you shall use some cross-platform serialization, result buffers or even better JSON strings are good options.

ZeroMQ has libraries for many languages, so you shall be able to communicate.

There is great ZeroMQ Guide providing clear explanation of concepts and showing implementation in many languages.

For planning the communication infrastructure, I would start with your Python script being bound to some TCP port (being "fixed" part) and your clients connecting to it.

Python script would use REP socket (for "reply"), your clients in other languages REQ sockets.

Following samples come from huge set of examples in zguide written for many languages

Sample Python server code (hwserver.py):

import zmq
import time

context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:5555")

while True:
    # Wait for next request from client
    message = socket.recv()
    print("Received request: %s" % message)

    # Do some 'work'
    time.sleep(1)

    # Send reply back to client
    socket.send(b"World")

Sample PHP client (hwclient.php):

<?php
/*
* Hello World client
* Connects REQ socket to tcp://localhost:5555
* Sends "Hello" to server, expects "World" back
* @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
*/

$context = new ZMQContext();

// Socket to talk to server
echo "Connecting to hello world server...\n";
$requester = new ZMQSocket($context, ZMQ::SOCKET_REQ);
$requester->connect("tcp://localhost:5555");

for ($request_nbr = 0; $request_nbr != 10; $request_nbr++) {
    printf ("Sending request %d...\n", $request_nbr);
    $requester->send("Hello");

    $reply = $requester->recv();
    printf ("Received reply %d: [%s]\n", $request_nbr, $reply);
}

Integration over shared data store

Shared file or database also allows communication between processes. The problem becomes complex with locking resources, taking care, that the same task is not processed by multiple workers etc.

Conclusion

There are multiple patterns and multiple platforms to implement.

  • database - you need to set it up and have it running. Might be too much for some small tasks.
  • shared file - possible conflict with sharing the file from multiple processes - if multiple processes try to write, there will be possibly a conflict.
  • messaging over TCP or UDP sockets - cold work, but in practice this is technically non-trivial as it has many cornercases you have to resolve (what to do, when one side gets down, reconnects...)
  • messaging over web services - you could set up web server, accepting requests from clients, processing on server. This is rather easy for quick tasks, but if the task takes more then 30 seconds, you probably fail and have to turn it to background processing - using some sort of messaging.
  • middle size and huge messaging systems (like Celery with RabbitMQ, Redis...) - have great tooling, could be overkill for many cases
  • messaging over ZeroMQ - this is my favourite - you can set it up in few lines of code and running without too many problems around - and it resolves problems like reconnects. etc. E.g. see full working example for distributed locker
halfer
  • 19,824
  • 17
  • 99
  • 186
Jan Vlcinsky
  • 42,725
  • 12
  • 101
  • 98
  • Sounds like the perfect approach. Thanks :) Do you know of other methods like these? How would this method compare to something like using a LAMP configuration, and using SQL module in python to interact with the database for this case? (I'm new to programming high level languages, so any background would help. I'm trying to determine what are other alternatives and when are they used) – sbhatla Jun 11 '14 at 18:32
  • @user2825720 I added more details about some options for integration. Have fun. – Jan Vlcinsky Jun 11 '14 at 18:53
  • You've explained it really great. Thank you so much. – sbhatla Jun 11 '14 at 20:05
1

Python has since early stages a very comfortable PyZMQ binding for ZeroMQ.

MATLAB can have the same, a direct ZeroMQ at work for your many-to-many communications.

Let me move in a bit broader view, from a few, but KEY PRINCIPAL POINTS, that are not so common in other software-engineering "products" & "stacks" we meet today around us:

[1] ZeroMQ is first of all a very powerful concept rather than a code or a DIY kit

[2] ZeroMQ's biggest plus for any professional grade project sits in rather using the genuine Scaleable Formal Communication Patterns end-to-end, not in the ability to code pieces or to "trick/mod" the published internals

[3] ZeroMQ team has done a terrific job and saves users from re-inventing wheels ("inside") and allows to rather stay on the most productive side by a re-use of the heroic knowledge ( elaborated, polished & tested by the ZeroMQ gurus, supporters & team-members ) from behind the ZMQ-abstraction-horizon.

Having said these few principles, my recommendation would be to spend some time on the concepts in a published book from Peter Hintjens on ZeroMQ ( also available in PDF). This a worthwhile place to start from, to get the bigger picture.

Then, there it would be a question of literally a few SLOC-s to make these world most powerful ( and believe me, that this sounds bold only on first sight, as there are not many real alternatives to compare ZeroMQ with ... well, ZeroMQ co-architect Martin Sustrik's [nanomsg] is that case, to mention at least one, if you need to go even higher in speed / lower in latency, but the above key principal points hold & remain the same even there ... )

Having used a ZeroMQ orchestrated Python & MQL4 & AI/ML system in FOREX high speed trading infrastructure environment is just a small example, where microseconds matter and nanosecond make a difference in the queue ...

Presented in a hope that your interest in ZeroMQ library will only grow & that you will benefit as much as many other uses of this brilliant piece of art have gained giant leap & benefited from whatever the PUB/SUB, PAIR/PAIR, REQ/REP formal patterns does best match the very communication need of your MATLAB / Python / * heterogeneous multi-party / multi-host Project.

halfer
  • 19,824
  • 17
  • 99
  • 186
user3666197
  • 1
  • 6
  • 50
  • 92