Mercurial > hg > orthanc
changeset 7096:63aae28fa10f streaming
reviewing documentation of new options
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Thu, 13 Aug 2026 13:18:38 +0000 |
| parents | 1e78972b48fa |
| children | 6d624dfcad3e |
| files | OrthancFramework/Sources/DataSource/DataSourceSequentialReader.h OrthancFramework/Sources/DataSource/DicomSequentialReader.h OrthancServer/Resources/AdvancedConfiguration.json OrthancServer/Resources/Configuration.json TODO |
| diffstat | 5 files changed, 60 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancFramework/Sources/DataSource/DataSourceSequentialReader.h Thu Aug 13 12:01:37 2026 +0000 +++ b/OrthancFramework/Sources/DataSource/DataSourceSequentialReader.h Thu Aug 13 13:18:38 2026 +0000 @@ -127,7 +127,7 @@ DataSourceSequentialReader(const boost::shared_ptr<IExecutorService>& executor, const boost::shared_ptr<DataSourceReader>& reader, IValueDisconnector* disconnector /* takes ownership */, - unsigned int windowSize /* number of elements in the sliding window */, + unsigned int windowSize /* maximum number of elements in the sliding window */, uint64_t windowCapacity /* if 0, memory usage is only controlled by the size of the sliding window */); ~DataSourceSequentialReader();
--- a/OrthancFramework/Sources/DataSource/DicomSequentialReader.h Thu Aug 13 12:01:37 2026 +0000 +++ b/OrthancFramework/Sources/DataSource/DicomSequentialReader.h Thu Aug 13 13:18:38 2026 +0000 @@ -117,8 +117,8 @@ const boost::shared_ptr<DataSourceReader>& storageAreaReader, const boost::shared_ptr<DataSourceReader>& dicomReader, const boost::shared_ptr<DataSourceReader>& transcoderReader, - unsigned int windowSize, - uint64_t windowCapacity); + unsigned int windowSize /* maximum number of elements in the sliding window */, + uint64_t windowCapacity /* if 0, memory usage is only controlled by the size of the sliding window */); const boost::shared_ptr<IExecutorService>& GetExecutorService() const {
--- a/OrthancServer/Resources/AdvancedConfiguration.json Thu Aug 13 12:01:37 2026 +0000 +++ b/OrthancServer/Resources/AdvancedConfiguration.json Thu Aug 13 13:18:38 2026 +0000 @@ -291,9 +291,6 @@ /** * Performance-related options - * - * TODO-Streaming: add a page in the book: performance: fine tuning: - * limiting memory + increasing the number of threads **/ // Defines the number of threads that are used to execute each type of @@ -327,7 +324,7 @@ // Default number of loader threads to use in jobs that read multiple files // from the storage area when executing some tasks, including: // - generating archive/media, - // - executing a C-Store, + // - executing a C-STORE, // - transmitting resources through Orthanc peering. // A value of 0 and 1 are equivalent: a single thread is used. // A value > 1 is meaningful only if the storage is a distributed network storage @@ -384,33 +381,45 @@ // cache. (new in Orthanc 1.13.0) "TranscoderCacheSize" : 256, - // Total number of threads that are used to provide DICOM files - // sequentially (currently used in Archive jobs, C-Store, and C-Get). - // Each time such a job needs to get a DICOM file content, it - // requests it from a sequential DICOM reader that will itself use a - // storage loader thread. Therefore, by default, the value of this - // configuration is identical to "StorageLoaderThreadsCount". You - // should monitor the "orthanc_seq_reader_available_threads" metrics - // to determine the optimal value for your setup and usage. (new in - // Orthanc 1.13.0) + // Number of threads for the sequential access to DICOM + // instances. When a thread in Orthanc needs a set of DICOM + // instances in a predefined order, it cannot rely directly on + // loader threads, which may provide the instances out of + // order. This is notably the case for archive jobs, C-STORE SCU + // connections, and C-GET SCP and C-MOVE SCP handlers. In such + // situations, Orthanc uses a sliding-window buffer that is + // populated by a set of threads calling the out-of-order loader + // threads. These preloading threads are part of a pool that is + // global to Orthanc. The threads are paused if the buffer grows too + // large before the calling thread consumes the instances. By + // default, this option has the same value as + // "StorageLoaderThreadsCount". You should monitor the + // "orthanc_seq_reader_available_threads" metrics to determine the + // optimal value for your setup and usage. (new in Orthanc 1.13.0) // "SequentialDicomReaderThreadsCount" : 4, - // Number of files each sequential DICOM reader is allowed to buffer - // in advance before it is consumed by the related job. - // This is kind of equivalent to the older "LoaderThreads" configuration - // but, furthermore, you must make sure that there are enough "StorageLoaderThreadsCount" - // and "SequentialDicomReaderThreadsCount" for each job -> - // "StorageLoaderThreadsCount" should be larger than "ConcurrentJobs" * "SequentialDicomReaderWindowSize" - // Together with "SequentialDicomReaderWindowCapacity", this also defines the amount of memory that is - // used by each job that required a SequentialDicomReader. - // By default, the value of this configuration is the same as "LoaderThreadsCount". (new in Orthanc 1.13.0) + // Each thread that accesses DICOM instances in sequential order + // creates a local sliding-window buffer that is preloaded by the + // global thread pool (cf. "SequentialDicomReaderThreadsCount"). + // This configuration option specifies the maximum number of DICOM + // instances that can be preloaded before they are consumed by the + // calling thread. Together with + // "SequentialDicomReaderWindowCapacity", this option determines the + // amount of memory used by each calling thread that requires + // sequential access to DICOM instances. This is roughly equivalent + // to the older "LoaderThreads" configuration: By default, this + // option is therefore set to the same value as "LoaderThreads", if + // the latter is available. (new in Orthanc 1.13.0) "SequentialDicomReaderWindowSize" : 4, - // Peak amount of RAM (in MB) that can be allocated by each - // sequential DICOM reader. The sequential DICOM reader pauses - // buffering as soon as one of the "SequentialDicomReaderWindowSize" - // or "SequentialDicomReaderWindowCapacity" limit is reached. Note - // that this limit can be exceeded when a single file is larger than - // this option. (new in Orthanc 1.13.0) - "SequentialDicomReaderWindowCapacity" : 64 + // Maximum amount of RAM (in MB) allocated to each local + // sliding-window buffer for each thread accessing a set of DICOM + // instances in sequential order (see + // "SequentialDicomReaderThreadsCount"). The global thread pool + // pauses preloading as soon as either the + // "SequentialDicomReaderWindowSize" or + // "SequentialDicomReaderWindowCapacity" limit is reached. Note that + // this limit can be exceeded when a single file is larger than the + // value specified by this option. (new in Orthanc 1.13.0) + "SequentialDicomReaderWindowCapacity" : 128 }
--- a/OrthancServer/Resources/Configuration.json Thu Aug 13 12:01:37 2026 +0000 +++ b/OrthancServer/Resources/Configuration.json Thu Aug 13 13:18:38 2026 +0000 @@ -37,9 +37,9 @@ // Action to take when the maximum storage is reached. // By default, the patients are recycled ("Recycle" mode). // In "Reject" mode, the sender will receive a 0xA700 DIMSE status code - // if the instance was sent through C-Store, a 507 HTTP status code + // if the instance was sent through C-STORE, a 507 HTTP status code // if using the REST API and a 0xA700 Failure reason when using - // DICOMweb Stow-RS. + // DICOMweb STOW-RS. // Note: this value is taken into account only if you have set // a MaximumStorageSize != 0 or a MaximumPatientCount != 0 // Allowed values: "Recycle", "Reject" @@ -483,9 +483,9 @@ // be run when Orthanc is acting as SCP. // Note: This is not limiting the number of concurrent connections // but the number of concurrent DICOM operations. - // For instance, with a single thread, if a C-Find request is received during - // e.g. the transcoding of an incoming C-Store, the C-Find will - // be processed only at the end of the C-Store operation but both + // For instance, with a single thread, if a C-FIND request is received during + // e.g. the transcoding of an incoming C-STORE, the C-FIND will + // be processed only at the end of the C-STORE operation but both // DICOM associations will remain active. // (new in Orthanc 1.10.0, before this version, the value was fixed to 4) "DicomThreadsCount" : 4,
--- a/TODO Thu Aug 13 12:01:37 2026 +0000 +++ b/TODO Thu Aug 13 13:18:38 2026 +0000 @@ -74,6 +74,18 @@ * Unable to cancel an ArchiveJob when Orthanc does not have access to the storage anymore. (To reproduce: remove the cable while downloading a study from S3) +* TODO-Streaming: This guideline was removed from + "AdvancedConfiguration.json" in the description of option + "SequentialDicomReaderWindowSize", as it might be incorrect in some + situations: + + // This is kind of equivalent to the older "LoaderThreads" configuration + // but, furthermore, you must make sure that there are enough "StorageLoaderThreadsCount" + // and "SequentialDicomReaderThreadsCount" for each job -> + // "StorageLoaderThreadsCount" should be larger than "ConcurrentJobs" * "SequentialDicomReaderWindowSize" + // Together with "SequentialDicomReaderWindowCapacity", this also defines the amount of memory that is + // used by each job that required a SequentialDicomReader. + ============================ Documentation (Orthanc Book) @@ -102,6 +114,8 @@ * Discuss HL7 in a dedicated page: https://groups.google.com/d/msg/orthanc-users/4dt4992O0lQ/opTjTFU2BgAJ https://groups.google.com/g/orthanc-users/c/Spjtcj9vSPo/m/ktUArWxUDQAJ +* TODO-Streaming: add a page in the book about performance (fine + tuning limiting memory + increasing the number of threads) ================
