comparison OrthancServer/Resources/Samples/Python/HighPerformanceAutoRouting.py @ 4044:d25f4c0fa160 framework

splitting code into OrthancFramework and OrthancServer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 10 Jun 2020 20:30:34 +0200
parents Resources/Samples/Python/HighPerformanceAutoRouting.py@94f4a18a79cc
children d9473bd5ed43
comparison
equal deleted inserted replaced
4043:6c6239aec462 4044:d25f4c0fa160
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 # Orthanc - A Lightweight, RESTful DICOM Store
5 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
6 # Department, University Hospital of Liege, Belgium
7 # Copyright (C) 2017-2020 Osimis S.A., Belgium
8 #
9 # This program is free software: you can redistribute it and/or
10 # modify it under the terms of the GNU General Public License as
11 # published by the Free Software Foundation, either version 3 of the
12 # License, or (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful, but
15 # WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 # General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22
23
24 URL = 'http://127.0.0.1:8042'
25 TARGET = 'sample'
26
27
28 #
29 # This sample code shows how to setup a simple, high-performance DICOM
30 # auto-routing. All the DICOM instances that arrive inside Orthanc
31 # will be sent to a remote modality. A producer-consumer pattern is
32 # used. The target modality is specified by the TARGET variable above:
33 # It must match an entry in the Orthanc configuration file inside the
34 # "DicomModalities" section.
35 #
36 # NOTE: This sample only works with Orthanc >= 0.5.2. Make sure that
37 # Orthanc was built with "-DCMAKE_BUILD_TYPE=Release" to get the best
38 # performance.
39 #
40
41 import Queue
42 import sys
43 import time
44 import threading
45
46 import RestToolbox
47
48
49 #
50 # Queue that is shared between the producer and the consumer
51 # threads. It holds the instances that are still to be sent.
52 #
53
54 queue = Queue.Queue()
55
56
57 #
58 # The producer thread. It monitors the arrival of new instances into
59 # Orthanc, and pushes their ID into the shared queue. This code is
60 # based upon the "ChangesLoop.py" sample code.
61 #
62
63 def Producer(queue):
64 current = 0
65
66 while True:
67 r = RestToolbox.DoGet(URL + '/changes', {
68 'since' : current,
69 'limit' : 4 # Retrieve at most 4 changes at once
70 })
71
72 for change in r['Changes']:
73 # We are only interested in the arrival of new instances
74 if change['ChangeType'] == 'NewInstance':
75 queue.put(change['ID'])
76
77 current = r['Last']
78
79 if r['Done']:
80 time.sleep(1)
81
82
83 #
84 # The consumer thread. It continuously reads the instances from the
85 # queue, and send them to the remote modality. Each time a packet of
86 # instances is sent, a single DICOM connexion is used, hence improving
87 # the performance.
88 #
89
90 def Consumer(queue):
91 TIMEOUT = 0.1
92
93 while True:
94 instances = []
95
96 while True:
97 try:
98 # Block for a while, waiting for the arrival of a new
99 # instance
100 instance = queue.get(True, TIMEOUT)
101
102 # A new instance has arrived: Record its ID
103 instances.append(instance)
104 queue.task_done()
105
106 except Queue.Empty:
107 # Timeout: No more data was received
108 break
109
110 if len(instances) > 0:
111 print('Sending a packet of %d instances' % len(instances))
112 start = time.time()
113
114 # Send all the instances with a single DICOM connexion
115 RestToolbox.DoPost('%s/modalities/sample/store' % URL, instances)
116
117 # Remove all the instances from Orthanc
118 for instance in instances:
119 RestToolbox.DoDelete('%s/instances/%s' % (URL, instance))
120
121 # Clear the log of the exported instances (to prevent the
122 # SQLite database from growing indefinitely). More simply,
123 # you could also set the "LogExportedResources" option to
124 # "false" in the configuration file since Orthanc 0.8.3.
125 RestToolbox.DoDelete('%s/exports' % URL)
126
127 end = time.time()
128 print('The packet of %d instances has been sent in %d seconds' % (len(instances), end - start))
129
130
131 #
132 # Thread to display the progress
133 #
134
135 def PrintProgress(queue):
136 while True:
137 print('Current queue size: %d' % (queue.qsize()))
138 time.sleep(1)
139
140
141 #
142 # Start the various threads
143 #
144
145 progress = threading.Thread(None, PrintProgress, None, (queue, ))
146 progress.daemon = True
147 progress.start()
148
149 producer = threading.Thread(None, Producer, None, (queue, ))
150 producer.daemon = True
151 producer.start()
152
153 consumer = threading.Thread(None, Consumer, None, (queue, ))
154 consumer.daemon = True
155 consumer.start()
156
157
158 #
159 # Active waiting for Ctrl-C
160 #
161
162 while True:
163 time.sleep(0.1)