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,47 @@
1
+ """
2
+ Set of rules and functions
3
+ Handling resubmission Block construction
4
+ """
5
+
6
+ from builtins import object
7
+
8
+ ACDC_PREFIX = "acdc"
9
+
10
+ class ACDCBlock(object):
11
+
12
+ @staticmethod
13
+ def name(wmspecName, taskName, offset, numOfFile):
14
+ taskName = taskName.replace('/', ':')
15
+ return "/%s/%s/%s/%s/%s" % (ACDC_PREFIX, wmspecName, taskName, offset,
16
+ numOfFile)
17
+
18
+ @staticmethod
19
+ def checkBlockName(blockName):
20
+ if blockName.split('/')[1] == ACDC_PREFIX:
21
+ return True
22
+ else:
23
+ return False
24
+
25
+ @staticmethod
26
+ def splitBlockName(blockName):
27
+ """ return False if the blockName is not acdc Block
28
+ return original elements of block name in order as a dict
29
+ {'SpecName': blockSplit[1],
30
+ 'TaskName': blockSplit[2],
31
+ 'Offset': int(blockSplit[3]),
32
+ 'NumOfFiles': int(blockSplit[4])},
33
+ if it is acdc Block
34
+ raise ValueError if the block is has wrong format
35
+ """
36
+ blockSplit = blockName.split('/')
37
+ if blockSplit[1] != ACDC_PREFIX:
38
+ return False
39
+ elif len(blockSplit) != 6:
40
+ msg = """blockName should contain prefix, wmspec name, task name,
41
+ offset and number of files %s""" % blockName
42
+ raise ValueError(msg)
43
+ else:
44
+ return {'SpecName': str(blockSplit[2]),
45
+ 'TaskName': str(blockSplit[3]).replace(':', '/'),
46
+ 'Offset': int(blockSplit[4]),
47
+ 'NumOfFiles': int(blockSplit[5])}
@@ -0,0 +1,48 @@
1
+ """
2
+ _Block_
3
+
4
+ A dictionary based object meant to represent a row in the active_block/block table.
5
+ """
6
+
7
+
8
+
9
+
10
+ class Block(dict):
11
+ """
12
+ _Block_
13
+
14
+ A dictionary based object meant to represent subset of dbs block.
15
+ Which will just need for workQueue update.
16
+ It contains the following keys:
17
+ Name
18
+ Size
19
+ NumEvent
20
+ NumFiles
21
+ """
22
+ def __init__(self, **args):
23
+ """
24
+ ___init___
25
+
26
+ Initialize all attributes.
27
+ """
28
+ dict.__init__(self)
29
+
30
+ self.setdefault("Name", None)
31
+ self.setdefault("Size", None)
32
+ self.setdefault("NumEvents", None)
33
+ self.setdefault("NumFiles", None)
34
+ self.update(args)
35
+
36
+ @staticmethod
37
+ def getBlock(blockInfo):
38
+ """
39
+ convert to the Block structure from db column format
40
+ """
41
+ block = Block()
42
+
43
+ block["Name"] = blockInfo[0]["name"]
44
+ block["NumFiles"] = blockInfo[0]["num_files"]
45
+ block["NumEvents"] = blockInfo[0]["num_events"]
46
+ block["Size"] = blockInfo[0]["block_size"]
47
+
48
+ return block
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env python
2
+ # encoding: utf-8
3
+ """
4
+ CouchWorkQueueElement.py
5
+
6
+ Created by Dave Evans on 2010-10-12.
7
+ Copyright (c) 2010 Fermilab. All rights reserved.
8
+ """
9
+
10
+ from future.utils import viewitems
11
+
12
+ import unittest
13
+ import time
14
+ import logging
15
+
16
+ from WMCore.Database.CMSCouch import Document
17
+ from WMCore.WorkQueue.DataStructs.WorkQueueElement import WorkQueueElement
18
+
19
+
20
+
21
+ class CouchWorkQueueElement(WorkQueueElement):
22
+ """
23
+ _CouchWorkQueueElement_
24
+
25
+ """
26
+ def __init__(self, couchDB, id = None, elementParams = None):
27
+ elementParams = elementParams or {}
28
+ WorkQueueElement.__init__(self, **elementParams)
29
+ if id:
30
+ self._id = id
31
+ self._document = Document(id = id)
32
+ self._couch = couchDB
33
+
34
+ rev = property(
35
+ lambda x: str(x._document[u'_rev']) if u'_rev' in x._document else x._document.__getitem__('_rev'),
36
+ lambda x, newid: x._document.__setitem__('_rev', newid))
37
+ timestamp = property(
38
+ lambda x: str(x._document[u'timestamp']) if u'timestamp' in x._document else x._document.__getitem__('timestamp')
39
+ )
40
+ updatetime = property(
41
+ lambda x: str(x._document[u'updatetime']) if u'updatetime' in x._document else 0
42
+ )
43
+
44
+
45
+ @classmethod
46
+ def fromDocument(cls, couchDB, doc):
47
+ """Create element from couch document"""
48
+ elementParams = doc.pop('WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement')
49
+ elementParams["CreationTime"] = doc.pop('timestamp')
50
+ element = CouchWorkQueueElement(couchDB = couchDB,
51
+ id = doc['_id'],
52
+ elementParams = elementParams)
53
+ element._document['_rev'] = doc.pop('_rev')
54
+ element._document['timestamp'] = elementParams["CreationTime"]
55
+ element._document['updatetime'] = doc.pop('updatetime')
56
+ return element
57
+
58
+ def save(self):
59
+ """
60
+ _save
61
+ """
62
+ self.populateDocument()
63
+ self._couch.queue(self._document)
64
+
65
+ def load(self):
66
+ """
67
+ _load_
68
+
69
+ Load the document representing this WQE
70
+ """
71
+ document = self._couch.document(self._document['_id'])
72
+ self.update(document.pop('WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement'))
73
+ self._document['_rev'] = document.pop('_rev')
74
+ self._document['timestamp'] = document.pop('timestamp', None)
75
+ self._document['updatetime'] = document.pop('updatetime', None)
76
+ return self
77
+
78
+ def delete(self):
79
+ """Delete element"""
80
+ self.populateDocument()
81
+ self._document.delete()
82
+ self._couch.queue(self._document)
83
+
84
+ def populateDocument(self):
85
+ """Certain attributed shouldn't be stored"""
86
+ self._document.update(self.__to_json__(None))
87
+ now = time.time()
88
+ self._document['updatetime'] = now
89
+ self._document.setdefault('timestamp', now)
90
+ if not self._document.get('_id') and self.id:
91
+ self._document['_id'] = self.id
92
+ attrs = ['WMSpec', 'Task']
93
+ for attr in attrs:
94
+ self._document['WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement'].pop(attr, None)
95
+
96
+
97
+
98
+ def fixElementConflicts(*elements):
99
+ """Take conflicting elements, fix conflicts and return
100
+ First element returned will contain the merged results,
101
+ the others will be losing revisions
102
+ """
103
+ ordered_states = ['Available', 'Negotiating', 'Acquired', 'Running',
104
+ 'Done', 'Failed', 'CancelRequested', 'Canceled']
105
+ allowed_keys = ['Status', 'EventsWritten', 'FilesProcessed',
106
+ 'PercentComplete', 'PercentSuccess', 'Inputs', 'NumOfFilesAdded',
107
+ 'SubscriptionId', 'Priority', 'SiteWhitelist', 'SiteBlacklist']
108
+ merged_value = None
109
+ updated = set()
110
+ for ele in elements:
111
+ if not merged_value: # 1st will contain merged result and become winner
112
+ merged_value = ele
113
+ continue
114
+
115
+ # print differences
116
+ from WMCore.Algorithms.MiscAlgos import dict_diff
117
+ logging.info("Conflict between %s revs %s & %s: %s",
118
+ ele.id, merged_value.rev, ele.rev,
119
+ "; ".join("%s=%s" % (x,y) for x,y in viewitems(dict_diff(merged_value, ele)))
120
+ )
121
+ for key in merged_value:
122
+ if merged_value[key] == ele.get(key):
123
+ continue
124
+ # we need to merge: Take elements from both that seem most advanced, e.g. status & progress stats
125
+ if key not in allowed_keys:
126
+ msg = 'Unable to merge conflicting element %s: field "%s" value 1 "%s" value2 "%s"'
127
+ raise RuntimeError(msg % (ele.id, key, merged_value.get(key), ele.get(key)))
128
+ elif key == 'Status':
129
+ if ordered_states.index(ele[key]) > ordered_states.index(merged_value[key]):
130
+ merged_value[key] = ele[key]
131
+ elif key == 'Inputs':
132
+ for item in merged_value[key]:
133
+ # take larger locations list
134
+ if merged_value[key][item] < ele[key].get(item, []):
135
+ merged_value[key][item] = ele[key][item]
136
+ elif ele[key] is not None and ele[key] > merged_value[key]:
137
+ merged_value[key] = ele[key]
138
+ updated.add(key)
139
+ # once losing element has been merged - queue for deletion
140
+ ele._document.delete()
141
+
142
+ msg = 'Resolving conflict for wf "%s", id "%s": Remove rev(s): %s: Updates: (%s)'
143
+ logging.info(msg, str(merged_value['RequestName']),
144
+ str(merged_value.id),
145
+ ", ".join([x._document['_rev'] for x in elements[1:]]),
146
+ "; ".join("%s=%s" % (x, merged_value[x]) for x in updated)
147
+ )
148
+ return elements
@@ -0,0 +1,274 @@
1
+ """
2
+ WorkQueueElement
3
+
4
+ A dictionary based object meant to represent a WorkQueue element
5
+ """
6
+
7
+ from future.utils import viewitems, viewvalues
8
+ import time
9
+ from hashlib import md5
10
+
11
+ from Utils.Utilities import encodeUnicodeToBytesConditional
12
+ from Utils.PythonVersion import PY3
13
+
14
+ STATES = ('Available', 'Negotiating', 'Acquired', 'Running',
15
+ 'Done', 'Failed', 'CancelRequested', 'Canceled')
16
+
17
+
18
+ def possibleSites(element):
19
+ """
20
+ _possibleSites_
21
+
22
+ Checks the site and data restrictions and return a list of possible sites
23
+ to work on this element.
24
+ """
25
+ # check if the whole document was provide
26
+ elem = element.get('WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement', element)
27
+
28
+ if elem['NoInputUpdate'] and elem['NoPileupUpdate']:
29
+ return elem['SiteWhitelist']
30
+
31
+ commonSites = set(elem['SiteWhitelist']) - set(elem['SiteBlacklist'])
32
+
33
+ if elem['Inputs'] and elem['NoInputUpdate'] is False:
34
+ commonSites = commonSites.intersection(set([y for x in viewvalues(elem['Inputs']) for y in x]))
35
+ if elem['ParentFlag'] and elem['NoInputUpdate'] is False:
36
+ commonSites = commonSites.intersection(set([y for x in viewvalues(elem['ParentData']) for y in x]))
37
+ if elem['PileupData'] and elem['NoPileupUpdate'] is False:
38
+ commonSites = commonSites.intersection(set([y for x in viewvalues(elem['PileupData']) for y in x]))
39
+
40
+ return list(commonSites)
41
+
42
+
43
+ class WorkQueueElement(dict):
44
+ """Class to represent a WorkQueue element"""
45
+
46
+ def __init__(self, **kwargs):
47
+ dict.__init__(self)
48
+
49
+ if 'Status' in kwargs and kwargs['Status'] not in STATES:
50
+ msg = 'Invalid Status: %s' % kwargs['Status']
51
+ raise ValueError(msg)
52
+
53
+ self.update(kwargs)
54
+
55
+ self._id = None
56
+
57
+ # XXX If adding or modifying any new parameter which affects the
58
+ # XXX workflow or data run over, the id function must be updated
59
+
60
+ self.setdefault('Inputs', {})
61
+ self.setdefault('ProcessedInputs', [])
62
+ self.setdefault('RejectedInputs', [])
63
+ # Some workflows require additional datasets for PileUp
64
+ # Track their locations
65
+ self.setdefault('PileupData', {})
66
+ # both ParentData and ParentFlag is needed in case there Dataset split,
67
+ # even though ParentFlag is True it will have empty ParentData
68
+ self.setdefault('ParentData', {})
69
+ self.setdefault('ParentFlag', False)
70
+ # 0 jobs are valid where we need to accept all blocks (only dqm etc subscriptions will run)
71
+ self.setdefault('Jobs', 0)
72
+ self.setdefault('WMSpec', None)
73
+ self.setdefault('SiteWhitelist', [])
74
+ self.setdefault('SiteBlacklist', [])
75
+ self.setdefault('Dbs', None)
76
+ self.setdefault('Task', None)
77
+ self.setdefault('ParentQueueId', None)
78
+ self.setdefault('Priority', 0)
79
+ self.setdefault('SubscriptionId', None)
80
+ self.setdefault('Status', None)
81
+ self.setdefault('EventsWritten', 0)
82
+ self.setdefault('FilesProcessed', 0)
83
+ self.setdefault('PercentComplete', 0)
84
+ self.setdefault('PercentSuccess', 0)
85
+ self.setdefault('RequestName', None)
86
+ self.setdefault('TaskName', None)
87
+ self.setdefault('TeamName', None)
88
+ self.setdefault('StartPolicy', {})
89
+ self.setdefault('EndPolicy', {})
90
+ self.setdefault('ACDC', {})
91
+ self.setdefault('ChildQueueUrl', None)
92
+ self.setdefault('ParentQueueUrl', None)
93
+ self.setdefault('WMBSUrl', None)
94
+ self.setdefault('NumberOfLumis', 0)
95
+ self.setdefault('NumberOfEvents', 0)
96
+ self.setdefault('NumberOfFiles', 0)
97
+ # Number of files added to WMBS including parent files for this element. used only for monitoring purpose
98
+ self.setdefault('NumOfFilesAdded', 0)
99
+ # Mask used to constrain MC run/lumi ranges
100
+ self.setdefault('Mask', None)
101
+ # is new data being added to the workflow (e.g., growing input datasets)
102
+ self.setdefault('OpenForNewData', False)
103
+ # EPOCH time for when the last block was found and added to the workflow
104
+ self.setdefault('TimestampFoundNewData', int(time.time()))
105
+ # Trust initial input dataset location only or not
106
+ self.setdefault('NoInputUpdate', False)
107
+ # Trust initial pileup dataset location only or not
108
+ self.setdefault('NoPileupUpdate', False)
109
+ # EPOCH time with the creation time for this wq element, needed for sorting
110
+ self.setdefault('CreationTime', int(time.time()))
111
+ # set to true when updated from a WorkQueueElementResult
112
+ self.modified = False
113
+
114
+ def __to_json__(self, thunker):
115
+ """Strip unthunkable"""
116
+ # result = WorkQueueElement(thunker_encoded_json = True,
117
+ result = dict(thunker_encoded_json=True,
118
+ type='WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement')
119
+ result['WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement'] = {}
120
+ result['WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement'].update(self)
121
+ # Do we need this 'Subscription' or can we not store this at all?
122
+ result['WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement'].pop('Subscription', None)
123
+ result['WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement'].pop('WMSpec', None)
124
+ # if self.get('Id'):
125
+ # result['_id'] = result['WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement'].pop('Id')
126
+ # if self.get('_rev'):
127
+ # result['_rev'] = result['WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement'].pop('_rev')
128
+ # result['Mask'] = thunker._thunk(result['Mask'])
129
+ return result
130
+
131
+ @property
132
+ def id(self):
133
+ """Generate id for element
134
+
135
+ id is deterministic and can be used to identify duplicate elements.
136
+ Calculation only includes fields which affect the workflow and input data.
137
+ Result is an md5 hash of a ';' separated list of:
138
+ workflow name, task name, list of inputs, mask, ACDC info, Dbs instance.
139
+
140
+ Parent file info not accounted.
141
+
142
+ Example:
143
+ >>> WorkQueueElement(RequestName = 'a', TaskName = 'b').id
144
+ '9ef03a6ad8f16d74fb5ba44df92bf1ef'
145
+
146
+ Warning: Any change to this function may prevent identical existing and
147
+ new elements from appearing equivalent, thus in the case of expanding
148
+ work subscriptions work duplication can occur. Care must be taken
149
+ if any modification is made.
150
+ """
151
+ if self._id:
152
+ return self._id
153
+ # Assume md5 is good enough for now
154
+ myhash = md5()
155
+ spacer = ';' # character not present in any field
156
+ myhash.update(encodeUnicodeToBytesConditional(self['RequestName'] + spacer, condition=PY3))
157
+ # Task will be None in global inbox
158
+ myhash.update(encodeUnicodeToBytesConditional(repr(self['TaskName']) + spacer, condition=PY3))
159
+ myhash.update(encodeUnicodeToBytesConditional(",".join(sorted(self['Inputs'].keys())) + spacer, condition=PY3))
160
+ # Check repr is reproducible - should be
161
+ if self['Mask']:
162
+ myhash.update(encodeUnicodeToBytesConditional(",".join(["%s=%s" % (x, y) for x, y in viewitems(self['Mask'])]) + spacer, condition=PY3))
163
+ else:
164
+ myhash.update(encodeUnicodeToBytesConditional("None" + spacer, condition=PY3))
165
+ # Check ACDC is deterministic and all params relevant
166
+ myhash.update(encodeUnicodeToBytesConditional(",".join(["%s=%s" % (x, y) for x, y in viewitems(self['ACDC'])]) + spacer, condition=PY3))
167
+ myhash.update(encodeUnicodeToBytesConditional(repr(self['Dbs']) + spacer, condition=PY3))
168
+ self._id = myhash.hexdigest()
169
+ return self._id
170
+
171
+ @id.setter
172
+ def id(self, value):
173
+ """Set id - use to override built-in id calculation"""
174
+ self._id = value
175
+
176
+ def __from_json__(self, jsondata, thunker):
177
+ """"""
178
+ self.update(jsondata)
179
+ return self
180
+
181
+ # self.update(jsondata['WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement'])
182
+ # self.pop('type', None)
183
+ # self.pop('thunker_encoded_json', None)
184
+ ## self['Id'] = jsondata['_id']
185
+ # self['_rev'] = jsondata['_rev'] # what to do here???
186
+ # return self
187
+
188
+ def inEndState(self):
189
+ """Have we finished processing"""
190
+ return self.isComplete() or self.isFailed() or self.isCanceled()
191
+
192
+ def isComplete(self):
193
+ return self['Status'] == 'Done'
194
+
195
+ def isFailed(self):
196
+ return self['Status'] == 'Failed'
197
+
198
+ def isRunning(self):
199
+ return self['Status'] == 'Running'
200
+
201
+ def isAcquired(self):
202
+ return self['Status'] == 'Acquired'
203
+
204
+ def isAvailable(self):
205
+ return self['Status'] == 'Available'
206
+
207
+ def isCanceled(self):
208
+ return self['Status'] == 'Canceled'
209
+
210
+ def isCancelRequested(self):
211
+ return self['Status'] == 'CancelRequested'
212
+
213
+ def updateFromSubscription(self, wmbsStatus):
214
+ """Get subscription status"""
215
+ mapping = {'EventsWritten': 'events_written',
216
+ 'FilesProcessed': 'files_processed',
217
+ 'PercentComplete': 'percent_complete',
218
+ 'PercentSuccess': 'percent_success'}
219
+ for ourkey, wmbskey in viewitems(mapping):
220
+ if wmbskey in wmbsStatus and self[ourkey] != wmbsStatus[wmbskey]:
221
+ self['Modified'] = True
222
+ self[ourkey] = wmbsStatus[wmbskey]
223
+
224
+ def updateWithResult(self, progressReport):
225
+ """Take a progress report and update ourself
226
+ Return True if progress updated"""
227
+ progressValues = ('Status', 'EventsWritten', 'FilesProcessed',
228
+ 'PercentComplete', 'PercentSuccess')
229
+ modified = False
230
+ for val in progressValues:
231
+ # ignore if values the same
232
+ if self[val] == progressReport[val]:
233
+ continue
234
+ # ignore new state if it is lower than the current state
235
+ if val == 'Status' and self[val] and STATES.index(progressReport[val]) <= STATES.index(self[val]):
236
+ continue
237
+
238
+ self[val] = progressReport[val]
239
+ modified = True
240
+ self.modified = modified
241
+
242
+ def statusMetrics(self):
243
+ """Returns the status & performance metrics"""
244
+ return dict(Status=self['Status'],
245
+ PercentComplete=self['PercentComplete'],
246
+ PercentSuccess=self['PercentSuccess'])
247
+
248
+ def passesSiteRestriction(self, site):
249
+ """
250
+ _passesSiteRestriction_
251
+
252
+ Given a site name, checks whether it passes the site and data restrictions.
253
+ """
254
+ # Site list restrictions
255
+ if site in self['SiteBlacklist'] or site not in self['SiteWhitelist']:
256
+ return False
257
+
258
+ # input data restrictions (TrustSitelists flag)
259
+ if self['NoInputUpdate'] is False:
260
+ for locations in viewvalues(self['Inputs']):
261
+ if site not in locations:
262
+ return False
263
+ if self['ParentFlag']:
264
+ for locations in viewvalues(self['ParentData']):
265
+ if site not in locations:
266
+ return False
267
+
268
+ # pileup data restrictions (TrustPUSitelists flag)
269
+ if self['NoPileupUpdate'] is False:
270
+ for locations in viewvalues(self['PileupData']):
271
+ if site not in locations:
272
+ return False
273
+
274
+ return True
@@ -0,0 +1,152 @@
1
+ """
2
+ WorkQueueElementResult
3
+
4
+ A dictionary based object meant to represent a WorkQueue block
5
+ """
6
+ from __future__ import division
7
+
8
+ #Can we re-use WorkQueueElement for this?
9
+
10
+
11
+
12
+
13
+ class WorkQueueElementResult(dict):
14
+ """Class to hold the status of a related group of WorkQueueElements"""
15
+ def __init__(self, **kwargs):
16
+ dict.__init__(self)
17
+ self.update(kwargs)
18
+
19
+ self.setdefault('WMSpec', None)
20
+ self.setdefault('Elements', [])
21
+ self.setdefault('Status', self.status())
22
+ if self['Elements']:
23
+ self.setdefault('EventsWritten',
24
+ sum([x['EventsWritten'] for x in self['Elements']]))
25
+ self.setdefault('FilesProcessed',
26
+ sum([x['FilesProcessed'] for x in self['Elements']]))
27
+ self.setdefault('Jobs', sum([x['Jobs'] for x in self['Elements']]))
28
+ self.setdefault('PercentComplete',
29
+ int(sum([x['PercentComplete'] for x in self['Elements']],
30
+ 0.0) / len(self['Elements'])))
31
+ self.setdefault('PercentSuccess',
32
+ int(sum([x['PercentSuccess'] for x in self['Elements']],
33
+ 0.0) / len(self['Elements'])))
34
+ self.setdefault('RequestName', self['Elements'][0]['RequestName'])
35
+ self.setdefault('TeamName', self['Elements'][0]['TeamName'])
36
+ self.setdefault('Priority', self['Elements'][0]['Priority'])
37
+ self.setdefault('ParentQueueId', self['Elements'][0]['ParentQueueId'])
38
+ elif self.get('ParentQueueElement'):
39
+ self.setdefault('EventsWritten', self['ParentQueueElement']['EventsWritten'])
40
+ self.setdefault('FilesProcessed', self['ParentQueueElement']['FilesProcessed'])
41
+ self.setdefault('Jobs', self['ParentQueueElement']['Jobs'])
42
+ self.setdefault('PercentComplete', self['ParentQueueElement']['PercentComplete'])
43
+ self.setdefault('PercentSuccess', self['ParentQueueElement']['PercentSuccess'])
44
+ self.setdefault('RequestName', self['ParentQueueElement']['RequestName'])
45
+ self.setdefault('TeamName', self['ParentQueueElement']['TeamName'])
46
+ self.setdefault('Priority', self['ParentQueueElement']['Priority'])
47
+ self.setdefault('ParentQueueId', self['ParentQueueElement'].id)
48
+ else:
49
+ raise RuntimeError("Can create WQEResult: No elements or parent provided")
50
+
51
+ # some cross checks
52
+ for i in self['Elements']:
53
+ assert(i['RequestName'] == self['RequestName'])
54
+ assert(i['TeamName'] == self['TeamName'])
55
+
56
+ def fractionComplete(self):
57
+ """Return fraction successful"""
58
+ return len(self.completeItems()) / float(len(self['Elements']))
59
+
60
+ def completeItems(self):
61
+ """Return complete items"""
62
+ return [x for x in self['Elements'] if x.isComplete()]
63
+
64
+ def failedItems(self):
65
+ """Return failed items"""
66
+ return [x for x in self['Elements'] if x.isFailed()]
67
+
68
+ def runningItems(self):
69
+ """Return acquired items"""
70
+ return [x for x in self['Elements'] if x.isRunning()]
71
+
72
+ def acquiredItems(self):
73
+ """Return available items"""
74
+ return [x for x in self['Elements'] if x.isAcquired()]
75
+
76
+ def availableItems(self):
77
+ """Return available items"""
78
+ return [x for x in self['Elements'] if x.isAvailable()]
79
+
80
+ def canceledItems(self):
81
+ """Return canceled items"""
82
+ return [x for x in self['Elements'] if x.isCanceled()]
83
+
84
+ def cancelRequestedItems(self):
85
+ """Return CancelRequested Items"""
86
+ return [x for x in self['Elements'] if x.isCancelRequested()]
87
+
88
+ def status(self):
89
+ """Compute status of elements"""
90
+ if not self['Elements'] and self.get('ParentQueueElement'):
91
+ return self['ParentQueueElement']['Status']
92
+ elif not self['Elements']:
93
+ return None
94
+
95
+ if not self.inEndState():
96
+ if self.cancelRequestedItems():
97
+ return 'CancelRequested'
98
+ elif self.runningItems():
99
+ return 'Running'
100
+ elif self.acquiredItems() or self.availableItems():
101
+ # available in local queue is acquired to parent
102
+ return 'Acquired'
103
+ else:
104
+ if self.canceledItems():
105
+ return "Canceled"
106
+ elif self.failedItems():
107
+ return "Failed"
108
+
109
+ # if all elements have same status take that
110
+ status = self['Elements'][0]['Status']
111
+ for element in self['Elements']:
112
+ if element['Status'] != status:
113
+ msg = "Unable to compute overall status of elements: %s"
114
+ raise RuntimeError(msg % str(self['Elements']))
115
+ return status
116
+
117
+ def inEndState(self):
118
+ """Are all requests complete (either success or failure)"""
119
+ if 'Status' in self:
120
+ return self['Status'] in ('Done', 'Failed', 'Canceled')
121
+ for element in self['Elements']:
122
+ if not element.inEndState():
123
+ return False
124
+ return True
125
+
126
+ def statusMetrics(self):
127
+ """Returns the status & performance metrics"""
128
+ keys = ['Status', 'PercentComplete', 'PercentSuccess']
129
+ return self.fromkeys(keys)
130
+
131
+ def formatForWire(self):
132
+ """Format used to send data over network
133
+ """
134
+ to_remove = ['Elements', 'WMSpec']
135
+ result = dict(self)
136
+ for item in to_remove:
137
+ result.pop(item)
138
+ return result
139
+
140
+ def getMaxJobElement(self):
141
+ maxJobElement = self['Elements'][0]
142
+ for x in self['Elements']:
143
+ if x['Jobs'] > maxJobElement['Jobs']:
144
+ maxJobElement = x
145
+ return maxJobElement
146
+
147
+ def getMinJobElement(self):
148
+ minJobElement = self['Elements'][0]
149
+ for x in self['Elements']:
150
+ if x['Jobs'] < minJobElement['Jobs']:
151
+ minJobElement = x
152
+ return minJobElement