changeset 4641:b02dc8303cf6

Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 27 Apr 2021 09:49:20 +0200
parents 66109d24d26e
children 69bbb4bd35cb
files NEWS OrthancServer/Sources/ServerJobs/ArchiveJob.cpp OrthancServer/Sources/ServerJobs/ArchiveJob.h
diffstat 3 files changed, 36 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Mon Apr 26 15:22:44 2021 +0200
+++ b/NEWS	Tue Apr 27 09:49:20 2021 +0200
@@ -2,6 +2,9 @@
 ===============================
 
 * "ETag" headers for metadata and attachments now allow strong comparison (MD5 is included)
+* Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media:
+  - In synchronous mode, their number could grow up to "JobsHistorySize" in Orthanc <= 1.9.2
+  - In asynchronous mode, the temporary files are removed as soon as their job gets canceled
 
 
 Version 1.9.2 (2021-04-22)
--- a/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp	Mon Apr 26 15:22:44 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp	Tue Apr 27 09:49:20 2021 +0200
@@ -931,7 +931,7 @@
   
   void ArchiveJob::Start()
   {
-    TemporaryFile* target = NULL;
+    TemporaryFile* target = NULL;  // (*)
     
     if (synchronousTarget_.get() == NULL)
     {
@@ -1008,6 +1008,17 @@
     writer_.reset();  // Flush all the results
 
     RefreshArchiveSize();
+
+    if (synchronousTarget_.get() != NULL)
+    {
+      /**
+       * Synchronous behavior: Release the reference to the temporary
+       * file. It is now up to the caller to deal with the shared
+       * pointer. This is a fix in Orthanc 1.9.3.
+       * https://groups.google.com/g/orthanc-users/c/tpP2fkRAd9o/m/5SGpEHbGCQAJ
+       **/
+      synchronousTarget_.reset();
+    }
     
     if (asynchronousTarget_.get() != NULL)
     {
@@ -1055,6 +1066,26 @@
   }
 
 
+  void ArchiveJob::Stop(JobStopReason reason)
+  {
+    /**
+     * New in Orthanc 1.9.3: Remove the temporary file associated with
+     * the job as soon as its job gets canceled (especially visible in
+     * asynchronous mode).
+     **/
+    if (reason == JobStopReason_Canceled ||
+        reason == JobStopReason_Failure ||
+        reason == JobStopReason_Retry)
+    {
+      // First delete the writer, as it holds a reference to "(a)synchronousTarget_", cf. (*)
+      writer_.reset();
+      
+      synchronousTarget_.reset();
+      asynchronousTarget_.reset();
+    }
+  }
+
+
   float ArchiveJob::GetProgress()
   {
     if (writer_.get() == NULL ||
--- a/OrthancServer/Sources/ServerJobs/ArchiveJob.h	Mon Apr 26 15:22:44 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.h	Tue Apr 27 09:49:20 2021 +0200
@@ -104,9 +104,7 @@
 
     virtual JobStepResult Step(const std::string& jobId) ORTHANC_OVERRIDE;
 
-    virtual void Stop(JobStopReason reason) ORTHANC_OVERRIDE
-    {
-    }
+    virtual void Stop(JobStopReason reason) ORTHANC_OVERRIDE;
 
     virtual float GetProgress() ORTHANC_OVERRIDE;