Merge branch '19320-spot-pricing'
[arvados.git] / services / api / app / models / container.rb
index 3334fdcac99802c0c370e51eb4621a48b87cbcb4..42d0ed49bf1f0ae5fdc5e9a0be6b152d57d1db70 100644 (file)
@@ -228,8 +228,10 @@ class Container < ArvadosModel
       rc['keep_cache_ram'] = Rails.configuration.Containers.DefaultKeepCacheRAM
     end
     if rc['keep_cache_disk'] == 0 and rc['keep_cache_ram'] == 0
-      # Only set if keep_cache_ram isn't set.
-      rc['keep_cache_disk'] = Rails.configuration.Containers.DefaultKeepCacheDisk
+      # If neither ram nor disk cache was specified and
+      # DefaultKeepCacheRAM==0, default to disk cache with size equal
+      # to RAM constraint (but at least 2 GiB and at most 32 GiB).
+      rc['keep_cache_disk'] = [[rc['ram'] || 0, 2 << 30].max, 32 << 30].min
     end
     rc
   end
@@ -310,6 +312,15 @@ class Container < ArvadosModel
       # records that don't have a 'cuda' section in runtime_constraints
       resolved_runtime_constraints << resolved_runtime_constraints[0].except('cuda')
     end
+    if resolved_runtime_constraints[0]['keep_cache_disk'] == 0
+      # If no disk cache requested, extend search to include older container
+      # records that don't have a 'keep_cache_disk' field in runtime_constraints
+      if resolved_runtime_constraints.length == 2
+        # exclude the one that also excludes CUDA
+        resolved_runtime_constraints << resolved_runtime_constraints[1].except('keep_cache_disk')
+      end
+      resolved_runtime_constraints << resolved_runtime_constraints[0].except('keep_cache_disk')
+    end
 
     candidates = candidates.where_serialized(:runtime_constraints, resolved_runtime_constraints, md5: true, multivalue: true)
     log_reuse_info(candidates) { "after filtering on runtime_constraints #{attrs[:runtime_constraints].inspect}" }
@@ -707,6 +718,31 @@ class Container < ArvadosModel
           end
 
           if retryable_requests.any?
+            scheduling_parameters = {
+              # partitions: empty if any are empty, else the union of all parameters
+              "partitions": retryable_requests
+                              .map { |req| req.scheduling_parameters["partitions"] || [] }
+                              .reduce { |cur, new| (cur.empty? or new.empty?) ? [] : (cur | new) },
+
+              # preemptible: true if all are true, else false
+              "preemptible": retryable_requests
+                               .map { |req| req.scheduling_parameters["preemptible"] }
+                               .all?,
+
+              # max_run_time: 0 if any are 0 (unlimited), else the maximum
+              "max_run_time": retryable_requests
+                                .map { |req| req.scheduling_parameters["max_run_time"] || 0 }
+                                .reduce do |cur, new|
+                if cur == 0 or new == 0
+                  0
+                elsif new > cur
+                  new
+                else
+                  cur
+                end
+              end,
+            }
+
             c_attrs = {
               command: self.command,
               cwd: self.cwd,
@@ -715,7 +751,7 @@ class Container < ArvadosModel
               container_image: self.container_image,
               mounts: self.mounts,
               runtime_constraints: self.runtime_constraints,
-              scheduling_parameters: self.scheduling_parameters,
+              scheduling_parameters: scheduling_parameters,
               secret_mounts: prev_secret_mounts,
               runtime_token: prev_runtime_token,
               runtime_user_uuid: self.runtime_user_uuid,