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,492 @@
1
+ from builtins import str, bytes, object
2
+ from future.utils import viewitems
3
+
4
+ from collections import defaultdict
5
+ from WMCore.Database.CMSCouch import CouchServer, CouchConflictError
6
+ from WMCore.Lexicon import splitCouchServiceURL
7
+ from WMCore.WMSpec.WMWorkload import WMWorkloadHelper
8
+ from WMCore.WorkQueue.DataStructs.WorkQueueElement import STATES
9
+ from WMCore.WorkQueue.DataStructs.CouchWorkQueueElement import CouchWorkQueueElement
10
+
11
+
12
+ def convertWQElementsStatusToWFStatus(elementsStatusSet):
13
+ """
14
+ Defined Workflow status from its WorkQeuueElement status.
15
+ :param: elementsStatusSet - dictionary of {request_name: set of all WQE status of this request, ...}
16
+ :returns: request status
17
+
18
+ Here is the mapping between request status and the GQE status
19
+ 1. acquired: all the GQEs are either Available or Negotiating.
20
+ Work is still in GQ, but not LQ.
21
+ 2. running-open: at least one of the GQEs are in Acquired status.
22
+ 3. running-closed: all the GQEs are in Running or beyond status.
23
+ No Available/Negotiating/Acquired status, all the work is in WMBS db (in agents)
24
+ 4. completed: all the GQEs are in a final status, like Done/Canceled/Failed.
25
+ All work is finished in WMBS (excluding cleanup and logcollect)
26
+ 5. failed: all the GQEs are in Failed status. If the workflow has multiple GQEs
27
+ and only a few are in Failed status, then just follow the usual request status.
28
+ 6. canceled: used to distinguish requests that have been correctly canceled,
29
+ coming from workflows either aborted or force-complete. This state does not
30
+ trigger a workflow status transition.
31
+ """
32
+ if not elementsStatusSet:
33
+ return None
34
+
35
+ forceCompleted = set(["CancelRequested"])
36
+ available = set(["Available", "Negotiating", "Failed"])
37
+ acquired = set(["Acquired"])
38
+ running = set(["Running"])
39
+ runningOpen = set(["Available", "Negotiating", "Acquired"])
40
+ runningClosed = set(["Running", "Done", "Canceled"])
41
+ canceled = set(["CancelRequested", "Done", "Canceled", "Failed"])
42
+ completed = set(["Done", "Canceled", "Failed"])
43
+ failed = set(["Failed"])
44
+
45
+ # Just a reminder:
46
+ # <= every element in the left set is also in the right set
47
+ # & return elements common between the left and right set
48
+ if elementsStatusSet == forceCompleted: # all WQEs in CancelRequested
49
+ return "canceled"
50
+ elif elementsStatusSet == acquired: # all WQEs in Acquired
51
+ return "running-open"
52
+ elif elementsStatusSet == running: # all WQEs in Running
53
+ return "running-closed"
54
+ elif elementsStatusSet == failed: # all WQEs in Failed
55
+ return "failed"
56
+ elif elementsStatusSet <= available: # all WQEs still in GQ
57
+ return "acquired"
58
+ elif elementsStatusSet <= completed: # all WQEs in a final state
59
+ return "completed"
60
+ elif elementsStatusSet <= canceled: # some WQEs still waiting to be cancelled
61
+ return "canceled"
62
+ elif elementsStatusSet & runningOpen: # at least 1 WQE still in GQ
63
+ return "running-open"
64
+ elif elementsStatusSet & runningClosed: # all WQEs already in LQ and WMBS
65
+ return "running-closed"
66
+ else:
67
+ # transitional status. Negotiating status won't be changed.
68
+ return None
69
+
70
+
71
+ # TODO: this could be derived from the Service class to use client side caching
72
+ class WorkQueue(object):
73
+ """
74
+ API for dealing with retrieving information from WorkQueue DataService
75
+ """
76
+
77
+ def __init__(self, couchURL, dbName=None, inboxDBName=None):
78
+ # if dbName not given assume we have to split
79
+ if not dbName:
80
+ couchURL, dbName = splitCouchServiceURL(couchURL)
81
+ self.hostWithAuth = couchURL
82
+ self.server = CouchServer(couchURL)
83
+ self.db = self.server.connectDatabase(dbName, create=False)
84
+ if not inboxDBName:
85
+ inboxDBName = "%s_inbox" % dbName
86
+ self.inboxDB = self.server.connectDatabase(inboxDBName, create=False)
87
+ self.defaultOptions = {'stale': "update_after", 'reduce': True, 'group': True}
88
+ self.eleKey = 'WMCore.WorkQueue.DataStructs.WorkQueueElement.WorkQueueElement'
89
+ self.states = STATES
90
+
91
+ def getTopLevelJobsByRequest(self):
92
+ """Get data items we have work in the queue for"""
93
+
94
+ data = self.db.loadView('WorkQueue', 'jobsByRequest', self.defaultOptions)
95
+ return [{'request_name': x['key'],
96
+ 'total_jobs': x['value']} for x in data.get('rows', [])]
97
+
98
+ def getChildQueuesAndStatus(self, stale=True):
99
+ """
100
+ Returns some stats for the workqueue elements in each ChildQueue and their status.
101
+ 1. total number of expected Jobs (sum)
102
+ 2. count of elements (count)
103
+ 3. minimum number of expected Jobs in an element
104
+ 4. maximum number of expected Jobs in an element
105
+ 5. sum of the squares of the expected Job in each element
106
+
107
+ Also reformat the output such that it's MONIT IT friendly and easier to aggregate.
108
+ """
109
+ options = {'reduce': True, 'group_level': 2}
110
+ if stale:
111
+ options['stale'] = 'update_after'
112
+
113
+ data = self.db.loadView('WorkQueue', 'jobsByChildQueueAndStatus', options)
114
+ result = []
115
+ for x in data.get('rows', []):
116
+ item = {'agent_name': self._getShortName(x['key'][0]),
117
+ 'status': x['key'][1]}
118
+ item.update(dict(sum_jobs=x['value']['sum'],
119
+ num_elem=x['value']['count'],
120
+ max_jobs_elem=x['value']['max']))
121
+ result.append(item)
122
+
123
+ return result
124
+
125
+ def getChildQueuesAndPriority(self, stale=True):
126
+ """
127
+ Returns some stats for the workqueue elements in each ChildQueue and their priority.
128
+ """
129
+ options = {'reduce': True, 'group_level': 2}
130
+ if stale:
131
+ options['stale'] = 'update_after'
132
+
133
+ data = self.db.loadView('WorkQueue', 'jobsByChildQueueAndPriority', options)
134
+ result = []
135
+ for x in data.get('rows', []):
136
+ item = {'agent_name': self._getShortName(x['key'][0]),
137
+ 'priority': int(x['key'][1])}
138
+ item.update(dict(sum_jobs=x['value']['sum'],
139
+ num_elem=x['value']['count'],
140
+ max_jobs_elem=x['value']['max']))
141
+ result.append(item)
142
+
143
+ return result
144
+
145
+ def _getShortName(self, longQueueName):
146
+ """
147
+ Get a full workqueue queue name (full hostname + port) and return its short name,
148
+ otherwise it fails to get injected into elastic search. E.g.:
149
+ from "http://cmssrv217.fnal.gov:5984" to "cmssrv217"
150
+ """
151
+ if longQueueName is None:
152
+ return "AgentNotDefined"
153
+ shortName = longQueueName.split('//')[-1]
154
+ shortName = shortName.split('.')[0]
155
+ return shortName
156
+
157
+ def getWMBSUrl(self):
158
+ """Get data items we have work in the queue for"""
159
+ data = self.db.loadView('WorkQueue', 'wmbsUrl', self.defaultOptions)
160
+ return [x['key'] for x in data.get('rows', [])]
161
+
162
+ def getWMBSUrlByRequest(self):
163
+ """Get data items we have work in the queue for"""
164
+ data = self.db.loadView('WorkQueue', 'wmbsUrlByRequest', self.defaultOptions)
165
+ return [{'request_name': x['key'][0],
166
+ 'wmbs_url': x['key'][1]} for x in data.get('rows', [])]
167
+
168
+ def getJobInjectStatusByRequest(self):
169
+ """
170
+ This service only provided by global queue
171
+ """
172
+ data = self.db.loadView('WorkQueue', 'jobInjectStatusByRequest',
173
+ self.defaultOptions)
174
+ return [{'request_name': x['key'][0], x['key'][1]: x['value']}
175
+ for x in data.get('rows', [])]
176
+
177
+ def getAnalyticsData(self):
178
+ """
179
+ This getInject status and input dataset from workqueue
180
+ """
181
+ results = self.db.loadView('WorkQueue', 'jobInjectStatusByRequest',
182
+ self.defaultOptions)
183
+ statusByRequest = {}
184
+ for x in results.get('rows', []):
185
+ statusByRequest.setdefault(x['key'][0], {})
186
+ statusByRequest[x['key'][0]][x['key'][1]] = x['value']
187
+
188
+ return statusByRequest
189
+
190
+ def getSiteWhitelistByRequest(self):
191
+ """
192
+ This service only provided by global queue
193
+ """
194
+ data = self.db.loadView('WorkQueue', 'siteWhitelistByRequest',
195
+ self.defaultOptions)
196
+ return [{'request_name': x['key'][0], 'site_whitelist': x['key'][1]}
197
+ for x in data.get('rows', [])]
198
+
199
+ def updateElements(self, *elementIds, **updatedParams):
200
+ """Update given element's (identified by id) with new parameters"""
201
+ if not elementIds:
202
+ return
203
+ eleParams = {}
204
+ if 'RequestPriority' in updatedParams:
205
+ updatedParams['Priority'] = updatedParams.pop('RequestPriority')
206
+ eleParams[self.eleKey] = updatedParams
207
+ conflictIDs = self.db.updateBulkDocumentsWithConflictHandle(elementIds, eleParams, maxConflictLimit=20)
208
+ if conflictIDs:
209
+ raise CouchConflictError("WQ update failed with conflict", data=updatedParams, result=conflictIDs, status=409)
210
+ return
211
+
212
+ def getAvailableWorkflows(self):
213
+ """Get the workflows that have all their elements
214
+ available in the workqueue"""
215
+ data = self.db.loadView('WorkQueue', 'elementsDetailByWorkflowAndStatus',
216
+ {'reduce': False, 'stale': 'update_after'})
217
+ availableSet = set((x['value']['RequestName'], x['value']['Priority']) for x in data.get('rows', []) if
218
+ x['key'][1] == 'Available')
219
+ notAvailableSet = set((x['value']['RequestName'], x['value']['Priority']) for x in data.get('rows', []) if
220
+ x['key'][1] != 'Available')
221
+ return availableSet - notAvailableSet
222
+
223
+ def cancelWorkflow(self, wf):
224
+ """
225
+ Cancel a workflow in both workqueue and workqueue_inbox database.
226
+ :param wf: string with the workflow name
227
+ :return: the status code for the couchdb update call
228
+ """
229
+ # first, update the single workflow workqueue_inbox element, if needed
230
+ inboxData = self.getOpenRequests(inboxFlag=True, options={"key": wf})
231
+ if inboxData:
232
+ updateParams = {self.eleKey: {"OpenForNewData": False}}
233
+ self.inboxDB.updateBulkDocuments(inboxData, updateParams)
234
+
235
+ # now update all of the workqueue elements
236
+ nonCancelableElements = ['Done', 'CancelRequested', 'Canceled', 'Failed']
237
+ data = self.db.loadView('WorkQueue', 'elementsDetailByWorkflowAndStatus',
238
+ {'startkey': [wf], 'endkey': [wf, {}],
239
+ 'reduce': False})
240
+ elements = [x['id'] for x in data.get('rows', []) if x['key'][1] not in nonCancelableElements]
241
+ return self.updateElements(*elements, Status='CancelRequested')
242
+
243
+ def updatePriority(self, wf, priority):
244
+ """Update priority of a workflow, this implies
245
+ updating the spec and the priority of the Available elements"""
246
+ # Update elements in Available status
247
+ data = self.db.loadView('WorkQueue', 'elementsDetailByWorkflowAndStatus',
248
+ {'startkey': [wf], 'endkey': [wf, {}],
249
+ 'reduce': False})
250
+ elementsToUpdate = [x['id'] for x in data.get('rows', [])]
251
+ if elementsToUpdate:
252
+ self.updateElements(*elementsToUpdate, Priority=priority)
253
+ # Update the spec, if it exists
254
+ if self.db.documentExists(wf):
255
+ wmspec = WMWorkloadHelper()
256
+ wmspec.load(self.hostWithAuth + "/%s/%s/spec" % (self.db.name, wf))
257
+ wmspec.setPriority(priority)
258
+ dummy_values = {'name': wmspec.name()}
259
+ wmspec.saveCouch(self.hostWithAuth, self.db.name, dummy_values)
260
+ return
261
+
262
+ def updateElementsByWorkflow(self, workload, updateParams, status=None):
263
+ """
264
+ Update all available WorkQueue elements of a given workflow with a set
265
+ of arguments provided through the `updateParams` dictionary
266
+ :param workload: A workflow spec
267
+ :param updateParams: A dictionary with parameters to be updated
268
+ :param status: A list of allowed WorkQueue elements statuses to be considered for updating
269
+ Default: None - do not filter by status
270
+ :return: No value, raises exceptions from internal methods in case of errors.
271
+ """
272
+ # Fetch the whole view with Workqueue elements per given workflow
273
+ wfName = workload.name()
274
+ data = self.db.loadView('WorkQueue', 'elementsDetailByWorkflowAndStatus',
275
+ {'startkey': [wfName], 'endkey': [wfName, {}],
276
+ 'reduce': False})
277
+
278
+ # Fetch only a list of WorkQueue element Ids && Filter them by allowed status
279
+ if status:
280
+ elementsToUpdate = [x['id'] for x in data.get('rows', []) if x['value']['Status'] in status]
281
+ else:
282
+ elementsToUpdate = [x['id'] for x in data.get('rows', [])]
283
+
284
+ # Update all WorkQueue elements with the parameters provided in a single push
285
+ if elementsToUpdate:
286
+ self.updateElements(*elementsToUpdate, **updateParams)
287
+
288
+ # Update the spec, if it exists
289
+ if self.db.documentExists(wfName):
290
+ # Update all workload parameters based on the full reqArgs dictionary
291
+ workload.updateWorkloadArgs(updateParams)
292
+ # Commit the changes of the current workload object to the database:
293
+ metadata = {'name': wfName}
294
+ workload.saveCouch(self.hostWithAuth, self.db.name, metadata=metadata)
295
+ return
296
+
297
+ def getWorkflowNames(self, inboxFlag=False):
298
+ """Get workflow names from workqueue db"""
299
+ if inboxFlag:
300
+ db = self.inboxDB
301
+ else:
302
+ db = self.db
303
+ data = db.loadView('WorkQueue', 'elementsByWorkflow', self.defaultOptions)
304
+ return [x['key'] for x in data.get('rows', [])]
305
+
306
+ def deleteWQElementsByWorkflow(self, workflowNames):
307
+ """
308
+ delete workqueue elements belongs to given workflow names
309
+ """
310
+ deleted = 0
311
+ dbs = [self.db, self.inboxDB]
312
+ if not isinstance(workflowNames, list):
313
+ workflowNames = [workflowNames]
314
+
315
+ if len(workflowNames) == 0:
316
+ return deleted
317
+
318
+ options = {}
319
+ options["stale"] = "ok"
320
+ options["reduce"] = False
321
+
322
+ for couchdb in dbs:
323
+ result = couchdb.loadView("WorkQueue", "elementsByWorkflow", options, workflowNames)
324
+ ids = []
325
+ for entry in result["rows"]:
326
+ ids.append(entry["id"])
327
+ if ids:
328
+ couchdb.bulkDeleteByIDs(ids)
329
+ deleted += len(ids)
330
+ return deleted
331
+
332
+ def getWQElementsByWorkflow(self, workflowNames, inboxFlag=False):
333
+ """
334
+ Get workqueue elements which belongs to a given workflow name(s)
335
+ :param workflowNames: The workflow name for which we try to fetch the WQE elemtns for (could be a list of names as well)
336
+ :param inboxFlag: A flag to switch quering the inboxDB as well (default: False)
337
+ :return: A list of WQEs
338
+ """
339
+ if inboxFlag:
340
+ couchdb = self.inboxDB
341
+ else:
342
+ couchdb = self.db
343
+
344
+ if not isinstance(workflowNames, list):
345
+ workflowNames = [workflowNames]
346
+
347
+ options = {}
348
+ options["stale"] = "ok"
349
+ options["reduce"] = False
350
+ options['include_docs'] = True
351
+
352
+ data = couchdb.loadView("WorkQueue", "elementsByWorkflow", options, workflowNames)
353
+ wqeList=[]
354
+ for wqe in data['rows']:
355
+ wqeList.append(CouchWorkQueueElement.fromDocument(couchdb, wqe['doc']))
356
+ return wqeList
357
+
358
+ def getElementsCountAndJobsByWorkflow(self, inboxFlag=False, stale=True):
359
+ """Get the number of elements and jobs by status and workflow"""
360
+ if inboxFlag:
361
+ db = self.inboxDB
362
+ else:
363
+ db = self.db
364
+ options = {'reduce': True, 'group_level': 2}
365
+ if stale:
366
+ options['stale'] = 'update_after'
367
+ data = db.loadView('WorkQueue', 'jobStatusByRequest', options)
368
+ result = defaultdict(dict)
369
+ for x in data.get('rows', []):
370
+ result[x['key'][0]][x['key'][1]] = {'NumOfElements': x['value']['count'],
371
+ 'Jobs': x['value']['sum']}
372
+ return result
373
+
374
+ def _retrieveWorkflowStatus(self, data):
375
+ workflowsStatus = {}
376
+
377
+ for workflow in data:
378
+ statusSet = set(data[workflow].keys())
379
+ status = convertWQElementsStatusToWFStatus(statusSet)
380
+ if status:
381
+ workflowsStatus[workflow] = status
382
+ return workflowsStatus
383
+
384
+ def getWorkflowStatusFromWQE(self, stale=True):
385
+ """
386
+ only checks workqueue db not inbox db.
387
+ returns and list of workflows by request status
388
+ """
389
+ data = self.getElementsCountAndJobsByWorkflow(stale=stale)
390
+ return self._retrieveWorkflowStatus(data)
391
+
392
+ def getCompletedWorkflow(self, stale=True):
393
+ """
394
+ only checks workqueue db not inbox db.
395
+ since inbox db will be cleaned up first when workflow is completed
396
+ """
397
+ workflowStatus = self.getWorkflowStatusFromWQE(stale=stale)
398
+ return [wf for wf, status in viewitems(workflowStatus) if status == "completed"]
399
+
400
+ def getJobsByStatus(self, inboxFlag=False, group=True):
401
+ """
402
+ For each WorkQueue element status, returns:
403
+ * total number of jobs (sum)
404
+ * number of workqueue elements (count)
405
+ * biggest number of jobs found in all those elements (max)
406
+
407
+ Use group=False in order to get a final summary of all the elements.
408
+ """
409
+ if inboxFlag:
410
+ db = self.inboxDB
411
+ else:
412
+ db = self.db
413
+ options = {'reduce': True, 'group': group, 'stale': 'update_after'}
414
+
415
+ data = db.loadView('WorkQueue', 'jobsByStatus', options)
416
+ result = {}
417
+ # Add all WorkQueueElement status to the output
418
+ for st in self.states:
419
+ result[st] = {}
420
+
421
+ for x in data.get('rows', []):
422
+ item = dict(sum_jobs=x['value']['sum'],
423
+ num_elem=x['value']['count'],
424
+ max_jobs_elem=x['value']['max'])
425
+ result[x['key']] = item
426
+
427
+ return result
428
+
429
+ def getJobsByStatusAndPriority(self, stale=True):
430
+ """
431
+ For each WorkQueue element status, returns a list of:
432
+ * workqueue element priority
433
+ * total number of jobs (sum)
434
+ * number of workqueue elements (count)
435
+ * biggest number of jobs found in all those elements (max)
436
+ """
437
+ options = {'reduce': True, 'group_level': 2}
438
+ if stale:
439
+ options['stale'] = 'update_after'
440
+
441
+ data = self.db.loadView('WorkQueue', 'jobsByStatusAndPriority', options)
442
+ result = {}
443
+ # Add all WorkQueueElement status to the output
444
+ for st in self.states:
445
+ result[st] = []
446
+
447
+ for x in data.get('rows', []):
448
+ st = x['key'][0]
449
+ prio = x['key'][1]
450
+ item = dict(priority=int(prio), sum_jobs=x['value']['sum'],
451
+ num_elem=x['value']['count'], max_jobs_elem=x['value']['max'])
452
+ result[st].append(item)
453
+
454
+ return result
455
+
456
+ def getElementsByStatus(self, status, inboxFlag=False, stale=True):
457
+ """
458
+ _getElementsByStatus_
459
+
460
+ Returns the whole elements in workqueue that match the list of status given.
461
+ """
462
+ if isinstance(status, (str, bytes)):
463
+ status = [status]
464
+
465
+ options = {'stale': 'update_after'} if stale else {}
466
+ options['include_docs'] = True
467
+
468
+ db = self.inboxDB if inboxFlag else self.db
469
+
470
+ data = db.loadView('WorkQueue', 'elementsByStatus', options, status)
471
+ result = {}
472
+ for x in data.get('rows', []):
473
+ # doc may have been deleted already
474
+ if x['doc']:
475
+ result.setdefault(x['key'], [])
476
+ result[x['key']].append(x['doc'])
477
+
478
+ return result
479
+
480
+ def getOpenRequests(self, inboxFlag=False, options=None):
481
+ """
482
+ Return workflow names that are still opened for new
483
+ data in workqueue
484
+ :param inboxFlag: boolean to select the *_inbox db
485
+ :param options: a dictionary that supports a few view parameters
486
+ :return: a list with unique request names
487
+ """
488
+ options = options or {}
489
+ options.setdefault("stale", "update_after")
490
+ db = self.inboxDB if inboxFlag else self.db
491
+ data = db.loadView('WorkQueue', 'openRequests', options)
492
+ return [x['key'] for x in data.get('rows', [])]
File without changes
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ _WMCore/Services_
4
+
5
+ Services for Workload Management Packages
6
+
7
+ """
8
+ __all__ = []