wmglobalqueue 2.4.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. Utils/CPMetrics.py +270 -0
  2. Utils/CertTools.py +100 -0
  3. Utils/EmailAlert.py +50 -0
  4. Utils/ExtendedUnitTestCase.py +62 -0
  5. Utils/FileTools.py +182 -0
  6. Utils/IteratorTools.py +80 -0
  7. Utils/MathUtils.py +31 -0
  8. Utils/MemoryCache.py +119 -0
  9. Utils/Patterns.py +24 -0
  10. Utils/Pipeline.py +137 -0
  11. Utils/PortForward.py +97 -0
  12. Utils/ProcFS.py +112 -0
  13. Utils/ProcessStats.py +194 -0
  14. Utils/PythonVersion.py +17 -0
  15. Utils/Signals.py +36 -0
  16. Utils/TemporaryEnvironment.py +27 -0
  17. Utils/Throttled.py +227 -0
  18. Utils/Timers.py +130 -0
  19. Utils/Timestamps.py +86 -0
  20. Utils/TokenManager.py +143 -0
  21. Utils/Tracing.py +60 -0
  22. Utils/TwPrint.py +98 -0
  23. Utils/Utilities.py +318 -0
  24. Utils/__init__.py +11 -0
  25. Utils/wmcoreDTools.py +707 -0
  26. WMCore/ACDC/Collection.py +57 -0
  27. WMCore/ACDC/CollectionTypes.py +12 -0
  28. WMCore/ACDC/CouchCollection.py +67 -0
  29. WMCore/ACDC/CouchFileset.py +238 -0
  30. WMCore/ACDC/CouchService.py +73 -0
  31. WMCore/ACDC/DataCollectionService.py +485 -0
  32. WMCore/ACDC/Fileset.py +94 -0
  33. WMCore/ACDC/__init__.py +11 -0
  34. WMCore/Algorithms/Alarm.py +39 -0
  35. WMCore/Algorithms/MathAlgos.py +274 -0
  36. WMCore/Algorithms/MiscAlgos.py +67 -0
  37. WMCore/Algorithms/ParseXMLFile.py +115 -0
  38. WMCore/Algorithms/Permissions.py +27 -0
  39. WMCore/Algorithms/Singleton.py +58 -0
  40. WMCore/Algorithms/SubprocessAlgos.py +129 -0
  41. WMCore/Algorithms/__init__.py +7 -0
  42. WMCore/Cache/GenericDataCache.py +98 -0
  43. WMCore/Cache/WMConfigCache.py +572 -0
  44. WMCore/Cache/__init__.py +0 -0
  45. WMCore/Configuration.py +659 -0
  46. WMCore/DAOFactory.py +47 -0
  47. WMCore/DataStructs/File.py +177 -0
  48. WMCore/DataStructs/Fileset.py +140 -0
  49. WMCore/DataStructs/Job.py +182 -0
  50. WMCore/DataStructs/JobGroup.py +142 -0
  51. WMCore/DataStructs/JobPackage.py +49 -0
  52. WMCore/DataStructs/LumiList.py +734 -0
  53. WMCore/DataStructs/Mask.py +219 -0
  54. WMCore/DataStructs/MathStructs/ContinuousSummaryHistogram.py +197 -0
  55. WMCore/DataStructs/MathStructs/DiscreteSummaryHistogram.py +92 -0
  56. WMCore/DataStructs/MathStructs/SummaryHistogram.py +117 -0
  57. WMCore/DataStructs/MathStructs/__init__.py +0 -0
  58. WMCore/DataStructs/Pickleable.py +24 -0
  59. WMCore/DataStructs/Run.py +256 -0
  60. WMCore/DataStructs/Subscription.py +175 -0
  61. WMCore/DataStructs/WMObject.py +47 -0
  62. WMCore/DataStructs/WorkUnit.py +112 -0
  63. WMCore/DataStructs/Workflow.py +60 -0
  64. WMCore/DataStructs/__init__.py +8 -0
  65. WMCore/Database/CMSCouch.py +1430 -0
  66. WMCore/Database/ConfigDBMap.py +29 -0
  67. WMCore/Database/CouchMonitoring.py +450 -0
  68. WMCore/Database/CouchUtils.py +118 -0
  69. WMCore/Database/DBCore.py +198 -0
  70. WMCore/Database/DBCreator.py +113 -0
  71. WMCore/Database/DBExceptionHandler.py +59 -0
  72. WMCore/Database/DBFactory.py +117 -0
  73. WMCore/Database/DBFormatter.py +177 -0
  74. WMCore/Database/Dialects.py +13 -0
  75. WMCore/Database/ExecuteDAO.py +327 -0
  76. WMCore/Database/MongoDB.py +241 -0
  77. WMCore/Database/MySQL/Destroy.py +42 -0
  78. WMCore/Database/MySQL/ListUserContent.py +20 -0
  79. WMCore/Database/MySQL/__init__.py +9 -0
  80. WMCore/Database/MySQLCore.py +132 -0
  81. WMCore/Database/Oracle/Destroy.py +56 -0
  82. WMCore/Database/Oracle/ListUserContent.py +19 -0
  83. WMCore/Database/Oracle/__init__.py +9 -0
  84. WMCore/Database/ResultSet.py +44 -0
  85. WMCore/Database/Transaction.py +91 -0
  86. WMCore/Database/__init__.py +9 -0
  87. WMCore/Database/ipy_profile_couch.py +438 -0
  88. WMCore/GlobalWorkQueue/CherryPyThreads/CleanUpTask.py +29 -0
  89. WMCore/GlobalWorkQueue/CherryPyThreads/HeartbeatMonitor.py +105 -0
  90. WMCore/GlobalWorkQueue/CherryPyThreads/LocationUpdateTask.py +28 -0
  91. WMCore/GlobalWorkQueue/CherryPyThreads/ReqMgrInteractionTask.py +35 -0
  92. WMCore/GlobalWorkQueue/CherryPyThreads/__init__.py +0 -0
  93. WMCore/GlobalWorkQueue/__init__.py +0 -0
  94. WMCore/GroupUser/CouchObject.py +127 -0
  95. WMCore/GroupUser/Decorators.py +51 -0
  96. WMCore/GroupUser/Group.py +33 -0
  97. WMCore/GroupUser/Interface.py +73 -0
  98. WMCore/GroupUser/User.py +96 -0
  99. WMCore/GroupUser/__init__.py +11 -0
  100. WMCore/Lexicon.py +836 -0
  101. WMCore/REST/Auth.py +202 -0
  102. WMCore/REST/CherryPyPeriodicTask.py +166 -0
  103. WMCore/REST/Error.py +333 -0
  104. WMCore/REST/Format.py +642 -0
  105. WMCore/REST/HeartbeatMonitorBase.py +90 -0
  106. WMCore/REST/Main.py +636 -0
  107. WMCore/REST/Server.py +2435 -0
  108. WMCore/REST/Services.py +24 -0
  109. WMCore/REST/Test.py +120 -0
  110. WMCore/REST/Tools.py +38 -0
  111. WMCore/REST/Validation.py +250 -0
  112. WMCore/REST/__init__.py +1 -0
  113. WMCore/ReqMgr/DataStructs/RequestStatus.py +209 -0
  114. WMCore/ReqMgr/DataStructs/RequestType.py +13 -0
  115. WMCore/ReqMgr/DataStructs/__init__.py +0 -0
  116. WMCore/ReqMgr/__init__.py +1 -0
  117. WMCore/Services/AlertManager/AlertManagerAPI.py +111 -0
  118. WMCore/Services/AlertManager/__init__.py +0 -0
  119. WMCore/Services/CRIC/CRIC.py +238 -0
  120. WMCore/Services/CRIC/__init__.py +0 -0
  121. WMCore/Services/DBS/DBS3Reader.py +1044 -0
  122. WMCore/Services/DBS/DBSConcurrency.py +44 -0
  123. WMCore/Services/DBS/DBSErrors.py +112 -0
  124. WMCore/Services/DBS/DBSReader.py +23 -0
  125. WMCore/Services/DBS/DBSUtils.py +166 -0
  126. WMCore/Services/DBS/DBSWriterObjects.py +381 -0
  127. WMCore/Services/DBS/ProdException.py +133 -0
  128. WMCore/Services/DBS/__init__.py +8 -0
  129. WMCore/Services/FWJRDB/FWJRDBAPI.py +118 -0
  130. WMCore/Services/FWJRDB/__init__.py +0 -0
  131. WMCore/Services/HTTPS/HTTPSAuthHandler.py +66 -0
  132. WMCore/Services/HTTPS/__init__.py +0 -0
  133. WMCore/Services/LogDB/LogDB.py +201 -0
  134. WMCore/Services/LogDB/LogDBBackend.py +191 -0
  135. WMCore/Services/LogDB/LogDBExceptions.py +11 -0
  136. WMCore/Services/LogDB/LogDBReport.py +85 -0
  137. WMCore/Services/LogDB/__init__.py +0 -0
  138. WMCore/Services/MSPileup/__init__.py +0 -0
  139. WMCore/Services/MSUtils/MSUtils.py +54 -0
  140. WMCore/Services/MSUtils/__init__.py +0 -0
  141. WMCore/Services/McM/McM.py +173 -0
  142. WMCore/Services/McM/__init__.py +8 -0
  143. WMCore/Services/MonIT/Grafana.py +133 -0
  144. WMCore/Services/MonIT/__init__.py +0 -0
  145. WMCore/Services/PyCondor/PyCondorAPI.py +154 -0
  146. WMCore/Services/PyCondor/__init__.py +0 -0
  147. WMCore/Services/ReqMgr/ReqMgr.py +261 -0
  148. WMCore/Services/ReqMgr/__init__.py +0 -0
  149. WMCore/Services/ReqMgrAux/ReqMgrAux.py +419 -0
  150. WMCore/Services/ReqMgrAux/__init__.py +0 -0
  151. WMCore/Services/RequestDB/RequestDBReader.py +267 -0
  152. WMCore/Services/RequestDB/RequestDBWriter.py +39 -0
  153. WMCore/Services/RequestDB/__init__.py +0 -0
  154. WMCore/Services/Requests.py +624 -0
  155. WMCore/Services/Rucio/Rucio.py +1290 -0
  156. WMCore/Services/Rucio/RucioUtils.py +74 -0
  157. WMCore/Services/Rucio/__init__.py +0 -0
  158. WMCore/Services/RucioConMon/RucioConMon.py +121 -0
  159. WMCore/Services/RucioConMon/__init__.py +0 -0
  160. WMCore/Services/Service.py +400 -0
  161. WMCore/Services/StompAMQ/__init__.py +0 -0
  162. WMCore/Services/TagCollector/TagCollector.py +155 -0
  163. WMCore/Services/TagCollector/XMLUtils.py +98 -0
  164. WMCore/Services/TagCollector/__init__.py +0 -0
  165. WMCore/Services/UUIDLib.py +13 -0
  166. WMCore/Services/UserFileCache/UserFileCache.py +160 -0
  167. WMCore/Services/UserFileCache/__init__.py +8 -0
  168. WMCore/Services/WMAgent/WMAgent.py +63 -0
  169. WMCore/Services/WMAgent/__init__.py +0 -0
  170. WMCore/Services/WMArchive/CMSSWMetrics.py +526 -0
  171. WMCore/Services/WMArchive/DataMap.py +463 -0
  172. WMCore/Services/WMArchive/WMArchive.py +33 -0
  173. WMCore/Services/WMArchive/__init__.py +0 -0
  174. WMCore/Services/WMBS/WMBS.py +97 -0
  175. WMCore/Services/WMBS/__init__.py +0 -0
  176. WMCore/Services/WMStats/DataStruct/RequestInfoCollection.py +300 -0
  177. WMCore/Services/WMStats/DataStruct/__init__.py +0 -0
  178. WMCore/Services/WMStats/WMStatsPycurl.py +145 -0
  179. WMCore/Services/WMStats/WMStatsReader.py +445 -0
  180. WMCore/Services/WMStats/WMStatsWriter.py +273 -0
  181. WMCore/Services/WMStats/__init__.py +0 -0
  182. WMCore/Services/WMStatsServer/WMStatsServer.py +134 -0
  183. WMCore/Services/WMStatsServer/__init__.py +0 -0
  184. WMCore/Services/WorkQueue/WorkQueue.py +492 -0
  185. WMCore/Services/WorkQueue/__init__.py +0 -0
  186. WMCore/Services/__init__.py +8 -0
  187. WMCore/Services/pycurl_manager.py +574 -0
  188. WMCore/WMBase.py +50 -0
  189. WMCore/WMConnectionBase.py +164 -0
  190. WMCore/WMException.py +183 -0
  191. WMCore/WMExceptions.py +269 -0
  192. WMCore/WMFactory.py +76 -0
  193. WMCore/WMInit.py +377 -0
  194. WMCore/WMLogging.py +104 -0
  195. WMCore/WMSpec/ConfigSectionTree.py +442 -0
  196. WMCore/WMSpec/Persistency.py +135 -0
  197. WMCore/WMSpec/Steps/BuildMaster.py +87 -0
  198. WMCore/WMSpec/Steps/BuildTools.py +201 -0
  199. WMCore/WMSpec/Steps/Builder.py +97 -0
  200. WMCore/WMSpec/Steps/Diagnostic.py +89 -0
  201. WMCore/WMSpec/Steps/Emulator.py +62 -0
  202. WMCore/WMSpec/Steps/ExecuteMaster.py +208 -0
  203. WMCore/WMSpec/Steps/Executor.py +210 -0
  204. WMCore/WMSpec/Steps/StepFactory.py +213 -0
  205. WMCore/WMSpec/Steps/TaskEmulator.py +75 -0
  206. WMCore/WMSpec/Steps/Template.py +204 -0
  207. WMCore/WMSpec/Steps/Templates/AlcaHarvest.py +76 -0
  208. WMCore/WMSpec/Steps/Templates/CMSSW.py +613 -0
  209. WMCore/WMSpec/Steps/Templates/DQMUpload.py +59 -0
  210. WMCore/WMSpec/Steps/Templates/DeleteFiles.py +70 -0
  211. WMCore/WMSpec/Steps/Templates/LogArchive.py +84 -0
  212. WMCore/WMSpec/Steps/Templates/LogCollect.py +105 -0
  213. WMCore/WMSpec/Steps/Templates/StageOut.py +105 -0
  214. WMCore/WMSpec/Steps/Templates/__init__.py +10 -0
  215. WMCore/WMSpec/Steps/WMExecutionFailure.py +21 -0
  216. WMCore/WMSpec/Steps/__init__.py +8 -0
  217. WMCore/WMSpec/Utilities.py +63 -0
  218. WMCore/WMSpec/WMSpecErrors.py +12 -0
  219. WMCore/WMSpec/WMStep.py +347 -0
  220. WMCore/WMSpec/WMTask.py +1997 -0
  221. WMCore/WMSpec/WMWorkload.py +2288 -0
  222. WMCore/WMSpec/WMWorkloadTools.py +382 -0
  223. WMCore/WMSpec/__init__.py +9 -0
  224. WMCore/WorkQueue/DataLocationMapper.py +273 -0
  225. WMCore/WorkQueue/DataStructs/ACDCBlock.py +47 -0
  226. WMCore/WorkQueue/DataStructs/Block.py +48 -0
  227. WMCore/WorkQueue/DataStructs/CouchWorkQueueElement.py +148 -0
  228. WMCore/WorkQueue/DataStructs/WorkQueueElement.py +274 -0
  229. WMCore/WorkQueue/DataStructs/WorkQueueElementResult.py +152 -0
  230. WMCore/WorkQueue/DataStructs/WorkQueueElementsSummary.py +185 -0
  231. WMCore/WorkQueue/DataStructs/__init__.py +0 -0
  232. WMCore/WorkQueue/Policy/End/EndPolicyInterface.py +44 -0
  233. WMCore/WorkQueue/Policy/End/SingleShot.py +22 -0
  234. WMCore/WorkQueue/Policy/End/__init__.py +32 -0
  235. WMCore/WorkQueue/Policy/PolicyInterface.py +17 -0
  236. WMCore/WorkQueue/Policy/Start/Block.py +258 -0
  237. WMCore/WorkQueue/Policy/Start/Dataset.py +180 -0
  238. WMCore/WorkQueue/Policy/Start/MonteCarlo.py +131 -0
  239. WMCore/WorkQueue/Policy/Start/ResubmitBlock.py +171 -0
  240. WMCore/WorkQueue/Policy/Start/StartPolicyInterface.py +316 -0
  241. WMCore/WorkQueue/Policy/Start/__init__.py +34 -0
  242. WMCore/WorkQueue/Policy/__init__.py +57 -0
  243. WMCore/WorkQueue/WMBSHelper.py +772 -0
  244. WMCore/WorkQueue/WorkQueue.py +1237 -0
  245. WMCore/WorkQueue/WorkQueueBackend.py +750 -0
  246. WMCore/WorkQueue/WorkQueueBase.py +39 -0
  247. WMCore/WorkQueue/WorkQueueExceptions.py +44 -0
  248. WMCore/WorkQueue/WorkQueueReqMgrInterface.py +278 -0
  249. WMCore/WorkQueue/WorkQueueUtils.py +130 -0
  250. WMCore/WorkQueue/__init__.py +13 -0
  251. WMCore/Wrappers/JsonWrapper/JSONThunker.py +342 -0
  252. WMCore/Wrappers/JsonWrapper/__init__.py +7 -0
  253. WMCore/Wrappers/__init__.py +6 -0
  254. WMCore/__init__.py +10 -0
  255. wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-patch +15 -0
  256. wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-unpatch +8 -0
  257. wmglobalqueue-2.4.5.1.data/data/bin/wmc-httpd +3 -0
  258. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/.couchapprc +1 -0
  259. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/README.md +40 -0
  260. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/index.html +264 -0
  261. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/ElementInfoByWorkflow.js +96 -0
  262. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/StuckElementInfo.js +57 -0
  263. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/WorkloadInfoTable.js +80 -0
  264. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/dataTable.js +70 -0
  265. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/namespace.js +23 -0
  266. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/style/main.css +75 -0
  267. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/couchapp.json +4 -0
  268. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/childQueueFilter.js +13 -0
  269. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/filterDeletedDocs.js +3 -0
  270. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/queueFilter.js +11 -0
  271. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/language +1 -0
  272. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/mustache.js +333 -0
  273. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/validate.js +27 -0
  274. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/workqueue_utils.js +61 -0
  275. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/elementsDetail.js +28 -0
  276. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/filter.js +86 -0
  277. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/stuckElements.js +38 -0
  278. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workRestrictions.js +153 -0
  279. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workflowSummary.js +28 -0
  280. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/rewrites.json +73 -0
  281. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/redirect.js +23 -0
  282. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/status.js +40 -0
  283. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/ElementSummaryByWorkflow.html +27 -0
  284. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/StuckElementSummary.html +26 -0
  285. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/TaskStatus.html +23 -0
  286. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/WorkflowSummary.html +27 -0
  287. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/workqueue-common-lib.html +2 -0
  288. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib-remote.html +16 -0
  289. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib.html +18 -0
  290. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/updates/in-place.js +50 -0
  291. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/validate_doc_update.js +8 -0
  292. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.couch.app.js +235 -0
  293. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.pathbinder.js +173 -0
  294. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/map.js +8 -0
  295. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/reduce.js +2 -0
  296. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/map.js +8 -0
  297. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/reduce.js +2 -0
  298. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/map.js +8 -0
  299. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/reduce.js +2 -0
  300. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/map.js +11 -0
  301. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/reduce.js +1 -0
  302. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/availableByPriority/map.js +6 -0
  303. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/conflicts/map.js +5 -0
  304. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elements/map.js +5 -0
  305. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByData/map.js +8 -0
  306. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParent/map.js +8 -0
  307. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParentData/map.js +8 -0
  308. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByPileupData/map.js +8 -0
  309. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByStatus/map.js +8 -0
  310. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsBySubscription/map.js +6 -0
  311. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/map.js +8 -0
  312. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/reduce.js +3 -0
  313. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsDetailByWorkflowAndStatus/map.js +26 -0
  314. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/map.js +10 -0
  315. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/reduce.js +1 -0
  316. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/map.js +6 -0
  317. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/reduce.js +1 -0
  318. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/map.js +6 -0
  319. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/reduce.js +1 -0
  320. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/map.js +6 -0
  321. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/reduce.js +1 -0
  322. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/map.js +6 -0
  323. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/reduce.js +1 -0
  324. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/map.js +6 -0
  325. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/reduce.js +1 -0
  326. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/map.js +6 -0
  327. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/reduce.js +1 -0
  328. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/openRequests/map.js +6 -0
  329. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/recent-items/map.js +5 -0
  330. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/map.js +6 -0
  331. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/reduce.js +1 -0
  332. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/specsByWorkflow/map.js +5 -0
  333. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/stuckElements/map.js +38 -0
  334. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/map.js +12 -0
  335. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/reduce.js +3 -0
  336. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/map.js +6 -0
  337. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/reduce.js +2 -0
  338. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/map.js +6 -0
  339. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/reduce.js +2 -0
  340. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/map.js +9 -0
  341. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/reduce.js +10 -0
  342. wmglobalqueue-2.4.5.1.dist-info/METADATA +26 -0
  343. wmglobalqueue-2.4.5.1.dist-info/RECORD +347 -0
  344. wmglobalqueue-2.4.5.1.dist-info/WHEEL +5 -0
  345. wmglobalqueue-2.4.5.1.dist-info/licenses/LICENSE +202 -0
  346. wmglobalqueue-2.4.5.1.dist-info/licenses/NOTICE +16 -0
  347. wmglobalqueue-2.4.5.1.dist-info/top_level.txt +2 -0
@@ -0,0 +1,185 @@
1
+ """
2
+ WorkQueueElementsSummary
3
+
4
+ """
5
+ from __future__ import (print_function, division)
6
+
7
+ from builtins import str, bytes, object
8
+ from future.utils import viewitems
9
+
10
+ from collections import defaultdict
11
+ from math import ceil
12
+
13
+ from WMCore.WorkQueue.DataStructs.WorkQueueElement import possibleSites
14
+ from WMCore.WorkQueue.DataStructs.WorkQueueElementResult import WorkQueueElementResult
15
+
16
+
17
+ def getGlobalSiteStatusSummary(elements, status=None, dataLocality=False):
18
+ """
19
+ _getGlobalSiteStatusSummary_
20
+
21
+ Given a dict with workqueue elements keyed by status, such as this format:
22
+ {u'Canceled': [{u'Inputs': {}, u'Jobs': 18,...}, {u'Jobs': 11,...}],
23
+ u'Running': [{'Priority': 190000,..}, ...]}
24
+
25
+ Creates a summary of jobs and number of wq elements in each status
26
+ distributed among the sites whitelisted. There are 2 job distribution:
27
+ *) unique top level jobs per site and per status and (equally
28
+ distributed among all sites)
29
+ *) possible top level jobs per site and per status (consider all
30
+ jobs can run in a single location)
31
+
32
+ If status is provided, then skip any workqueue element not in the
33
+ given status. Otherwise filter only active workqueue status.
34
+
35
+ If dataLocality is set to True, then it considers only sites that pass
36
+ the data location constraint.
37
+ """
38
+ if status and isinstance(status, (str, bytes)):
39
+ activeStatus = [status]
40
+ elif status and isinstance(status, (list, tuple)):
41
+ activeStatus = status
42
+ else:
43
+ activeStatus = list(elements)
44
+
45
+ uniqueJobsSummary = {}
46
+ possibleJobsSummary = {}
47
+
48
+ for st in activeStatus:
49
+ uniqueJobsSummary.setdefault(st, {})
50
+ possibleJobsSummary.setdefault(st, {})
51
+ uniqueJobs = {}
52
+ possibleJobs = {}
53
+ for elem in elements.get(st, []):
54
+ elem = elem['WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement']
55
+ if dataLocality:
56
+ commonSites = possibleSites(elem)
57
+ else:
58
+ commonSites = list(set(elem['SiteWhitelist']) - set(elem['SiteBlacklist']))
59
+
60
+ try:
61
+ jobsPerSite = elem['Jobs'] / len(commonSites)
62
+ except ZeroDivisionError:
63
+ commonSites = ['NoPossibleSite']
64
+ jobsPerSite = elem['Jobs']
65
+
66
+ for site in commonSites:
67
+ uniqueJobs.setdefault(site, {'sum_jobs': 0, 'num_elem': 0})
68
+ possibleJobs.setdefault(site, {'sum_jobs': 0, 'num_elem': 0})
69
+
70
+ uniqueJobs[site]['sum_jobs'] += ceil(jobsPerSite)
71
+ uniqueJobs[site]['num_elem'] += 1
72
+ possibleJobs[site]['sum_jobs'] += ceil(elem['Jobs'])
73
+ possibleJobs[site]['num_elem'] += 1
74
+
75
+ uniqueJobsSummary[st].update(uniqueJobs)
76
+ possibleJobsSummary[st].update(possibleJobs)
77
+
78
+ return uniqueJobsSummary, possibleJobsSummary
79
+
80
+
81
+ class WorkQueueElementsSummary(object):
82
+ """Class to hold the status of a related group of WorkQueueElements"""
83
+ def __init__(self, elements):
84
+ self.elements = elements
85
+
86
+ elementsByRequest = {}
87
+ for ele in elements:
88
+ elementsByRequest.setdefault(ele["RequestName"], [])
89
+ elementsByRequest[ele["RequestName"]].append(ele)
90
+
91
+ self.wqResultsByRequest = {}
92
+ for reqName, wqElements in viewitems(elementsByRequest):
93
+ self.wqResultsByRequest[reqName] = WorkQueueElementResult(Elements=wqElements)
94
+
95
+ def elementsWithHigherPriorityInSameSites(self, requestName, returnFormat="dict"):
96
+
97
+ if requestName not in self.wqResultsByRequest:
98
+ return None
99
+
100
+ priority = self.wqResultsByRequest[requestName]['Priority']
101
+ creationTime = self.wqResultsByRequest[requestName]['Elements'][0]['CreationTime']
102
+
103
+ sites = self.getPossibleSitesByRequest(requestName)
104
+
105
+ sortedElements = []
106
+ for reqName in self.wqResultsByRequest:
107
+ # skip the workflow
108
+ if reqName == requestName:
109
+ continue
110
+ if self.wqResultsByRequest[reqName]['Priority'] >= priority:
111
+ for element in self.wqResultsByRequest[reqName]['Elements']:
112
+ if element['CreationTime'] > creationTime:
113
+ continue
114
+ if len(sites) > 0:
115
+ commonSites = possibleSites(element)
116
+ if len(set(commonSites) & sites) > 0:
117
+ sortedElements.append(element)
118
+ else:
119
+ sortedElements.append(element)
120
+ # sort elements to get them in priority first and timestamp order
121
+ sortedElements.sort(key=lambda element: element['CreationTime'])
122
+ sortedElements.sort(key = lambda x: x['Priority'], reverse = True)
123
+ if returnFormat == "list":
124
+ return sortedElements
125
+ elif returnFormat == "dict":
126
+ sortedByRequest = defaultdict(list)
127
+ for ele in sortedElements:
128
+ sortedByRequest[ele['RequestName']].append(ele)
129
+
130
+ for request in sortedByRequest:
131
+ sortedByRequest[request] = WorkQueueElementResult(Elements=sortedByRequest[request])
132
+ return sortedByRequest
133
+
134
+ def getPossibleSitesByRequest(self, requestName):
135
+
136
+ if requestName not in self.wqResultsByRequest:
137
+ return None
138
+ # this will include all the possible sites on the requests
139
+ # TODO: when different blocks are located in different site it need to handled
140
+ sites = set()
141
+ for ele in self.wqResultsByRequest[requestName]['Elements']:
142
+ sites = sites | set(possibleSites(ele))
143
+ return sites
144
+
145
+ def getWQElementResultsByRequest(self, requestName = None):
146
+ if requestName:
147
+ return self.wqResultsByRequest.get(requestName, None)
148
+ else:
149
+ return self.wqResultsByRequest
150
+
151
+ def printSummary(self, request, detail=False):
152
+
153
+ wqResult = self.getWQElementResultsByRequest(request)
154
+
155
+ if wqResult is None:
156
+ print("No WQ element exist for the status given")
157
+ return
158
+ print("### summary for %s ###" % request )
159
+ print(" Priority: %s, available elements: %s " % (wqResult["Priority"], len(wqResult['Elements'])))
160
+
161
+ sites = self.getPossibleSitesByRequest(request)
162
+ print(" Possible sites to run: %s" % list(sites))
163
+
164
+ higher = self.elementsWithHigherPriorityInSameSites(request)
165
+ total = 0
166
+ totalJobs = 0
167
+ for request in higher:
168
+ wqResult = higher[request]
169
+ availableEle = wqResult.availableItems()
170
+ if not availableEle:
171
+ continue
172
+ total += len(availableEle)
173
+ wqAvailResult = WorkQueueElementResult(Elements=availableEle)
174
+ totalJobs += wqAvailResult['Jobs']
175
+ maxJobEle = wqAvailResult.getMaxJobElement()
176
+ minJobEle = wqAvailResult.getMinJobElement()
177
+ if detail:
178
+ print(" Higher priority elements by request:")
179
+ print("""%s: Priority: %s, available elements: %s, total jobs: %s,
180
+ max jobs: %s (element_id: %s), min jobs: %s (element_id: %s)""" % (
181
+ request, wqAvailResult["Priority"], availableEle, wqAvailResult['Jobs'],
182
+ maxJobEle["Jobs"], maxJobEle.id,
183
+ minJobEle["Jobs"], minJobEle.id))
184
+ print(" Higher priority elements: %s, total available jobs: %s" % (total, totalJobs))
185
+
File without changes
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ WorkQueue EndPolicyInterface
4
+
5
+ """
6
+
7
+
8
+
9
+
10
+ from WMCore.WorkQueue.Policy.PolicyInterface import PolicyInterface
11
+ from WMCore.WorkQueue.DataStructs.WorkQueueElementResult import WorkQueueElementResult as WQEResult
12
+
13
+ class EndPolicyInterface(PolicyInterface):
14
+ """Interface for end policies"""
15
+ def __init__(self, **args):
16
+ PolicyInterface.__init__(self, **args)
17
+ self.results = []
18
+
19
+ def __call__(self, elements, parents):
20
+ """Apply policy to given elements"""
21
+ for parent in parents:
22
+ elements_for_parent = []
23
+ for element in elements:
24
+ if element['ParentQueueId'] == parent.id:
25
+ elements_for_parent.append(element)
26
+ result = WQEResult(ParentQueueId = parent.id,
27
+ ParentQueueElement = parent,
28
+ Elements = elements_for_parent)
29
+ self.results.append(result)
30
+
31
+ self.applyPolicy() # do plugin logic
32
+ return self.results
33
+
34
+ def applyPolicy(self):
35
+ """Extend in sub classes for custom behaviour"""
36
+ forceStatus = None
37
+ for result in self.results:
38
+ result['ParentQueueElement'].updateWithResult(result)
39
+ # check for a cancellation request
40
+ if result['ParentQueueElement'].isCancelRequested():
41
+ forceStatus = 'CancelRequested'
42
+ if forceStatus:
43
+ # cancel whole request
44
+ [x.__setitem__('Status', forceStatus) for x in self.results]
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env python
2
+ """
3
+
4
+ SingleShot EndPolicy
5
+
6
+ """
7
+
8
+
9
+
10
+
11
+ from WMCore.WorkQueue.Policy.End.EndPolicyInterface import EndPolicyInterface
12
+
13
+ class SingleShot(EndPolicyInterface):
14
+ """
15
+ o No Retries
16
+ """
17
+ def __init__(self, **args):
18
+ EndPolicyInterface.__init__(self, **args)
19
+
20
+ def applyPolicy(self):
21
+ """Apply the given policy"""
22
+ EndPolicyInterface.applyPolicy(self)
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ WorkQueue End Policy
4
+
5
+ """
6
+
7
+ from WMCore.WMFactory import WMFactory
8
+
9
+ endFac = WMFactory(__name__, __name__)
10
+
11
+
12
+ def endPolicy(elements, parents=None, args=None):
13
+ """Load an end policy"""
14
+
15
+ # load policy and apply
16
+ if not args:
17
+ args = {}
18
+ if elements:
19
+ policy = elements[0]['EndPolicy']
20
+ elif parents:
21
+ policy = parents[0]['EndPolicy']
22
+ else:
23
+ raise RuntimeError("Can't get policy, no elements or parents")
24
+ name = policy['policyName']
25
+ args = args.get(name, {})
26
+ args.update(policy)
27
+ return endFac.loadObject(name,
28
+ args,
29
+ storeInCache=False)(elements, parents)
30
+
31
+
32
+ __all__ = []
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ WorkQueue PolicyInterface
4
+
5
+ """
6
+ from builtins import object
7
+ import logging
8
+ from copy import deepcopy
9
+
10
+
11
+
12
+
13
+ class PolicyInterface(object):
14
+ """Interface for policies"""
15
+ def __init__(self, **args):
16
+ self.logger = args.pop('logger') if args.get('logger') else logging.getLogger()
17
+ self.args = deepcopy(args)
@@ -0,0 +1,258 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ WorkQueue splitting by block
4
+
5
+ """
6
+ from __future__ import print_function, division
7
+
8
+ import logging
9
+ from math import ceil
10
+
11
+ from WMCore.WorkQueue.Policy.Start.StartPolicyInterface import StartPolicyInterface
12
+ from WMCore.WorkQueue.WorkQueueExceptions import WorkQueueWMSpecError
13
+ from WMCore.WorkQueue.WorkQueueUtils import makeLocationsList
14
+ from WMCore import Lexicon
15
+
16
+
17
+ class Block(StartPolicyInterface):
18
+ """Split elements into blocks"""
19
+
20
+ def __init__(self, **args):
21
+ StartPolicyInterface.__init__(self, **args)
22
+ self.args.setdefault('SliceType', 'NumberOfFiles')
23
+ self.args.setdefault('SliceSize', 1)
24
+ self.lumiType = "NumberOfLumis"
25
+
26
+ # Initialize a list of sites where the data is
27
+ self.sites = []
28
+
29
+ # Initialize modifiers of the policy
30
+ self.blockBlackListModifier = []
31
+
32
+ def split(self):
33
+ """Apply policy to spec"""
34
+ dbs = self.dbs()
35
+ for block in self.validBlocks(self.initialTask, dbs):
36
+ # set the parent flag for processing only for clarity on the couch doc
37
+ parentList = {}
38
+ parentFlag = False
39
+ # TODO this is slow process needs to change in DBS3
40
+ if self.initialTask.parentProcessingFlag():
41
+ parentFlag = True
42
+ parentBlocks = dbs.listBlockParents(block["block"])
43
+ for blockName in parentBlocks:
44
+ if self.initialTask.getTrustSitelists().get('trustlists'):
45
+ parentList[blockName] = self.sites
46
+ else:
47
+ blockLocations = self.blockLocationRucioPhedex(blockName)
48
+ parentList[blockName] = self.cric.PNNstoPSNs(blockLocations)
49
+
50
+ # there could be 0 event files in that case we can't estimate the number of jobs created.
51
+ # We set Jobs to 1 for that case.
52
+ # If we need more realistic estimate, we need to dry run the spliting the jobs.
53
+ estimateJobs = max(1, ceil(block[self.args['SliceType']] / self.args['SliceSize']))
54
+
55
+ self.newQueueElement(Inputs={block['block']: self.data.get(block['block'], [])},
56
+ ParentFlag=parentFlag,
57
+ ParentData=parentList,
58
+ NumberOfLumis=int(block[self.lumiType]),
59
+ NumberOfFiles=int(block['NumberOfFiles']),
60
+ NumberOfEvents=int(block['NumberOfEvents']),
61
+ Jobs=estimateJobs,
62
+ OpenForNewData=False,
63
+ NoInputUpdate=self.initialTask.getTrustSitelists().get('trustlists'),
64
+ NoPileupUpdate=self.initialTask.getTrustSitelists().get('trustPUlists')
65
+ )
66
+
67
+ def validate(self):
68
+ """Check args and spec work with block splitting"""
69
+ StartPolicyInterface.validateCommon(self)
70
+
71
+ if not self.initialTask.inputDataset():
72
+ raise WorkQueueWMSpecError(self.wmspec, 'No input dataset')
73
+
74
+ def validBlocks(self, task, dbs):
75
+ """Return blocks that pass the input data restriction"""
76
+ datasetPath = task.getInputDatasetPath()
77
+ validBlocks = []
78
+
79
+ blockWhiteList = task.inputBlockWhitelist()
80
+ blockBlackList = task.inputBlockBlacklist()
81
+ runWhiteList = task.inputRunWhitelist()
82
+ runBlackList = task.inputRunBlacklist()
83
+ if task.getLumiMask(): # if we have a lumi mask get only the relevant blocks
84
+ maskedBlocks = self.getMaskedBlocks(task, dbs, datasetPath)
85
+ if task.getTrustSitelists().get('trustlists'):
86
+ siteWhitelist = task.siteWhitelist()
87
+ siteBlacklist = task.siteBlacklist()
88
+ self.sites = makeLocationsList(siteWhitelist, siteBlacklist)
89
+
90
+ blocks = []
91
+ # Take data inputs or from spec
92
+ if not self.data:
93
+ if blockWhiteList:
94
+ self.data = dict((block, []) for block in blockWhiteList)
95
+ else:
96
+ self.data = {datasetPath: []} # same structure as in WorkQueueElement
97
+
98
+ for data in self.data:
99
+ if data.find('#') > -1:
100
+ Lexicon.block(data) # check block name
101
+ datasetPath = str(data.split('#')[0])
102
+ blocks.append(str(data))
103
+ else:
104
+ Lexicon.dataset(data) # check dataset name
105
+ for block in dbs.listFileBlocks(data):
106
+ blocks.append(str(block))
107
+
108
+ for blockName in blocks:
109
+ # check block restrictions
110
+ if blockWhiteList and blockName not in blockWhiteList:
111
+ continue
112
+ if blockName in blockBlackList:
113
+ continue
114
+ if blockName in self.blockBlackListModifier:
115
+ # Don't duplicate blocks rejected before or blocks that were included and therefore are now in the blacklist
116
+ continue
117
+ if task.getLumiMask() and blockName not in maskedBlocks:
118
+ logging.warning("Block %s doesn't pass the lumi mask constraints", blockName)
119
+ self.rejectedWork.append(blockName)
120
+ continue
121
+
122
+ block = self._getBlockSummary(dbs, datasetPath, blockName)
123
+ if not block:
124
+ continue
125
+
126
+ # check lumi restrictions
127
+ if task.getLumiMask():
128
+ accepted_lumis = sum([len(maskedBlocks[blockName][lfn].getLumis()) for lfn in maskedBlocks[blockName]])
129
+ # use the information given from getMaskedBlocks to compute che size of the block
130
+ block['NumberOfFiles'] = len(maskedBlocks[blockName])
131
+ # ratio = lumis which are ok in the block / total num lumis
132
+ ratioAccepted = accepted_lumis / block['NumberOfLumis']
133
+ block['NumberOfEvents'] = block['NumberOfEvents'] * ratioAccepted
134
+ block[self.lumiType] = accepted_lumis
135
+ # check run restrictions
136
+ elif runWhiteList or runBlackList:
137
+ # listRunLumis returns a dictionary with the lumi sections per run
138
+ runLumis = dbs.listRunLumis(block=block['block'])
139
+ runs = set(runLumis.keys())
140
+ recalculateLumiCounts = False
141
+ if len(runs) > 1:
142
+ # If more than one run in the block
143
+ # Then we must calculate the lumi counts after filtering the run list
144
+ # This has to be done rarely and requires calling DBS file information
145
+ recalculateLumiCounts = True
146
+
147
+ # apply blacklist
148
+ runs = runs.difference(runBlackList)
149
+ # if whitelist only accept listed runs
150
+ if runWhiteList:
151
+ runs = runs.intersection(runWhiteList)
152
+ # any runs left are ones we will run on, if none ignore block
153
+ if not runs:
154
+ logging.warning("Block %s doesn't pass the runs constraints", blockName)
155
+ self.rejectedWork.append(blockName)
156
+ continue
157
+
158
+ if len(runs) == len(runLumis):
159
+ # If there is no change in the runs, then we can skip recalculating lumi counts
160
+ recalculateLumiCounts = False
161
+
162
+ if recalculateLumiCounts:
163
+ # Recalculate effective size of block
164
+ # We pull out file info, since we don't do this often
165
+ acceptedLumiCount = 0
166
+ acceptedEventCount = 0
167
+ acceptedFileCount = 0
168
+ fileInfo = dbs.listFilesInBlock(fileBlockName=block['block'])
169
+ for fileEntry in fileInfo:
170
+ acceptedFile = False
171
+ acceptedFileLumiCount = 0
172
+ for lumiInfo in fileEntry['LumiList']:
173
+ runNumber = lumiInfo['RunNumber']
174
+ if runNumber in runs:
175
+ acceptedFile = True
176
+ acceptedFileLumiCount += 1
177
+ acceptedLumiCount += len(lumiInfo['LumiSectionNumber'])
178
+ if acceptedFile:
179
+ acceptedFileCount += 1
180
+ if len(fileEntry['LumiList']) != acceptedFileLumiCount:
181
+ acceptedEventCount += acceptedFileLumiCount * fileEntry['NumberOfEvents'] / len(fileEntry['LumiList'])
182
+ else:
183
+ acceptedEventCount += fileEntry['NumberOfEvents']
184
+ block[self.lumiType] = acceptedLumiCount
185
+ block['NumberOfFiles'] = acceptedFileCount
186
+ block['NumberOfEvents'] = acceptedEventCount
187
+ # save locations
188
+ if task.getTrustSitelists().get('trustlists'):
189
+ self.data[block['block']] = self.sites
190
+ else:
191
+ blockLocations = self.blockLocationRucioPhedex(block['block'])
192
+ self.data[block['block']] = self.cric.PNNstoPSNs(blockLocations)
193
+
194
+ # TODO: need to decide what to do when location is no find.
195
+ # There could be case for network problem (no connection to dbs, phedex)
196
+ # or DBS se is not recorded (This will be retried anyway by location mapper)
197
+ if not self.data[block['block']]:
198
+ self.data[block['block']] = ["NoInitialSite"]
199
+ # # No sites for this block, move it to rejected
200
+ # self.rejectedWork.append(blockName)
201
+ # continue
202
+
203
+ validBlocks.append(block)
204
+ return validBlocks
205
+
206
+ def _getBlockSummary(self, dbsObj, datasetPath, blockName):
207
+ """
208
+ Retrieve a summary for this block from both DBS and Rucio. If the block
209
+ has 0 valid files in DBS, or 0 files in Rucio, it is then marked as
210
+ rejected and skipped from the work creation. Otherwise, the DBS summary
211
+ is returned.
212
+ :param dbsObj: instance to the DBS3Reader object
213
+ :param datasetPath: string with the input dataset name
214
+ :param blockName: string with the block name
215
+ :return: either an empty dictionary, or the DBS summary dictionary
216
+ """
217
+ # blocks with 0 valid files should be ignored
218
+ # - ideally they would be deleted but dbs can't delete blocks
219
+ block = dbsObj.getDBSSummaryInfo(dataset=datasetPath, block=blockName)
220
+ if int(block.get('NumberOfFiles', 0)) == 0:
221
+ logging.warning("Block %s being rejected for lack of valid files in DBS to process", blockName)
222
+ self.badWork.append(blockName)
223
+ return dict()
224
+ # blocks with 0 files in Rucio should be ignored as well
225
+ blockRucio = self.rucio.getDID(didName=blockName, dynamic=False)
226
+ if not blockRucio.get('length'):
227
+ logging.warning("Block %s being rejected for lack of files in Rucio to process", blockName)
228
+ self.badWork.append(blockName)
229
+ return dict()
230
+ return block
231
+
232
+ def modifyPolicyForWorkAddition(self, inboxElement):
233
+ """
234
+ A block blacklist modifier will be created,
235
+ this policy object will split excluding the blocks in both the spec
236
+ blacklist and the blacklist modified
237
+ """
238
+ # Get the already processed input blocks from the inbox element
239
+ self.blockBlackListModifier = inboxElement.get('ProcessedInputs', [])
240
+ self.blockBlackListModifier.extend(inboxElement.get('RejectedInputs', []))
241
+
242
+ def newDataAvailable(self, task, inbound):
243
+ """
244
+ In the case of the block policy, the new data available
245
+ returns True if it finds at least one open block.
246
+ """
247
+ self.initialTask = task
248
+ dbs = self.dbs()
249
+ allBlocks = dbs.listFileBlocks(task.getInputDatasetPath())
250
+ newBlocks = set(allBlocks) - set(self.rejectedWork) - set(self.badWork)
251
+ return bool(newBlocks)
252
+
253
+ @staticmethod
254
+ def supportsWorkAddition():
255
+ """
256
+ Block start policy supports continuous addition of work
257
+ """
258
+ return True