# HG changeset patch # User Sebastien Jodogne # Date 1367319261 -7200 # Node ID 4b9a7010b1ea9d79b82fda0e52a55556978c8f65 # Parent c3e9b74aab7aee24e85765249b698074d7ded236 sample of routing diff -r c3e9b74aab7a -r 4b9a7010b1ea Resources/Samples/Python/HighPerformanceAutoRouting.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Samples/Python/HighPerformanceAutoRouting.py Tue Apr 30 12:54:21 2013 +0200 @@ -0,0 +1,138 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + + +URL = 'http://localhost:8042' +TARGET = 'sample' + + +# +# This sample code shows how to setup a simple, high-performance DICOM +# auto-routing. All the DICOM instances that arrive inside Orthanc +# will be sent to a remote modality. A producer-consumer pattern is +# used. The target modality is specified by the TARGET variable above: +# It must match an entry in the Orthanc configuration file inside the +# "DicomModalities" section. +# +# NOTE: This sample only works with Orthanc >= 0.5.2. Make sure that +# Orthanc was built with "-DCMAKE_BUILD_TYPE=Release" to get the best +# performance. +# + +import Queue +import sys +import time +import threading + +import RestToolbox + + +# +# Queue that is shared between the producer and the consumer +# threads. It holds the instances that are still to be sent. +# + +queue = Queue.Queue() + + +# +# The producer thread. It monitors the arrival of new instances into +# Orthanc, and pushes their ID into the shared queue. This code is +# based upon the "ChangesLoop.py" sample code. +# + +def Producer(queue): + current = 0 + + while True: + r = RestToolbox.DoGet(URL + '/changes', { + 'since' : current, + 'limit' : 4 # Retrieve at most 4 changes at once + }) + + for change in r['Changes']: + # We are only interested interested in the arrival of new instances + if change['ChangeType'] == 'NewInstance': + queue.put(change['ID']) + + current = r['Last'] + + if r['Done']: + time.sleep(1) + + +# +# The consumer thread. It continuously reads the instances from the +# queue, and send them to the remote modality. Each time a packet of +# instances is sent, a single DICOM connexion is used, hence improving +# the performance. +# + +def Consumer(queue): + TIMEOUT = 0.1 + + while True: + instances = [] + + while True: + try: + # Block for a while, waiting for the arrival of a new + # instance + instance = queue.get(True, TIMEOUT) + + # A new instance has arrived: Record its ID + instances.append(instance) + queue.task_done() + + except Queue.Empty: + # Timeout: No more data was received + break + + if len(instances) > 0: + print 'Sending a packet of %d instances' % len(instances) + start = time.time() + + # Send all the instances with a single DICOM connexion + RestToolbox.DoPost('%s/modalities/sample/store' % URL, instances) + + # Remove all the instances from Orthanc + for instance in instances: + RestToolbox.DoDelete('%s/instances/%s' % (URL, instance)) + + end = time.time() + print 'The packet of %d instances has been sent in %d seconds' % (len(instances), end - start) + + +# +# Thread to display the progress +# + +def PrintProgress(queue): + while True: + print 'Current queue size: %d' % (queue.qsize()) + time.sleep(1) + + +# +# Start the various threads +# + +progress = threading.Thread(None, PrintProgress, None, (queue, )) +progress.daemon = True +progress.start() + +producer = threading.Thread(None, Producer, None, (queue, )) +producer.daemon = True +producer.start() + +consumer = threading.Thread(None, Consumer, None, (queue, )) +consumer.daemon = True +consumer.start() + + +# +# Active waiting for Ctrl-C +# + +while True: + time.sleep(0.1)