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,256 @@
1
+ #!/usr/bin/env python
2
+
3
+ """
4
+ _Run_
5
+
6
+ container representing a run, and its constituent lumi sections and event counts
7
+ """
8
+
9
+ from __future__ import print_function
10
+ from future.utils import viewitems, listitems
11
+
12
+ import hashlib
13
+ from builtins import str as newstr, bytes as newbytes
14
+ from Utils.PythonVersion import PY3
15
+ from Utils.Utilities import encodeUnicodeToBytesConditional, encodeUnicodeToBytes
16
+ from WMCore.DataStructs.WMObject import WMObject
17
+
18
+
19
+ class Run(WMObject):
20
+ """
21
+ _Run_
22
+
23
+ Run container, is a list of lumi sections with associate event counts
24
+
25
+ TODO
26
+ - use the decorator `from functools import total_ordering` after
27
+ dropping support for python 2.6
28
+ - then, drop __ne__, __le__, __gt__, __ge__
29
+ """
30
+
31
+ def __init__(self, runNumber=None, *newLumis):
32
+ WMObject.__init__(self)
33
+ self.run = runNumber
34
+ self.eventsPerLumi = {}
35
+ self.extendLumis(newLumis)
36
+
37
+ def __str__(self):
38
+ return "Run%s:%s" % (self.run, self.eventsPerLumi)
39
+
40
+ def __eq__(self, rhs):
41
+ """
42
+ Check equality of run numbers and then underlying lumi/event dicts
43
+ """
44
+ if not isinstance(rhs, Run):
45
+ return False
46
+ if self.run != rhs.run:
47
+ return False
48
+ return self.eventsPerLumi == rhs.eventsPerLumi
49
+
50
+ def __ne__(self, rhs):
51
+ return not self.__eq__(rhs)
52
+
53
+ def __lt__(self, rhs):
54
+ """
55
+ Compare on run # first, then by lumis as a list, then by events in each lumi
56
+ """
57
+ # check run number
58
+ if self.run != rhs.run:
59
+ return self.run < rhs.run
60
+ # if same run number, check list of lumi sections
61
+ if sorted(self.eventsPerLumi.keys()) != sorted(rhs.eventsPerLumi.keys()):
62
+ return sorted(self.eventsPerLumi.keys()) < sorted(rhs.eventsPerLumi.keys())
63
+ # if same list of lumis, check events in each lumi section
64
+ for lumiNumber in sorted(self.eventsPerLumi):
65
+ if self.eventsPerLumi[lumiNumber] == rhs.eventsPerLumi.get(lumiNumber):
66
+ continue
67
+ else:
68
+ return self.eventsPerLumi[lumiNumber] < rhs.eventsPerLumi.get(lumiNumber)
69
+ # if same run number, same lumi sections list,
70
+ # same events in each lumi section:
71
+ # then the runs are equal and __lt__ should return false
72
+ return False
73
+
74
+ def __le__(self, other):
75
+ return self.__lt__(other) or self.__eq__(other)
76
+
77
+ def __gt__(self, other):
78
+ return not self.__le__(other)
79
+
80
+ def __ge__(self, other):
81
+ return not self.__lt__(other)
82
+
83
+ def extend(self, items):
84
+ """
85
+ Redirect to the function that already does this
86
+ """
87
+ self.extendLumis(items)
88
+ return
89
+
90
+ def __add__(self, rhs):
91
+ """
92
+ Combine two runs
93
+ """
94
+ if self.run != rhs.run:
95
+ msg = "Adding together two different runs"
96
+ msg += "Run %s does not equal Run %s" % (self.run, rhs.run)
97
+ raise RuntimeError(msg)
98
+
99
+ for lumi, events in viewitems(rhs.eventsPerLumi):
100
+ if lumi not in self.eventsPerLumi or not self.eventsPerLumi[lumi]: # Either doesn't exist, 0, or None
101
+ self.eventsPerLumi[lumi] = events
102
+ else:
103
+ self.eventsPerLumi[lumi] += events
104
+ return self
105
+
106
+ def __iter__(self):
107
+ return self.eventsPerLumi.__iter__()
108
+
109
+ def __next__(self):
110
+ """
111
+ __next__ no longer needed
112
+ """
113
+ raise NotImplementedError
114
+
115
+ def __len__(self):
116
+ """
117
+ Number of lumis
118
+ """
119
+ return self.eventsPerLumi.__len__()
120
+
121
+ def __getitem__(self, key):
122
+ """
123
+ Get the nth lumi from the list (no event count)
124
+ """
125
+ return sorted(self.eventsPerLumi.keys()).__getitem__(key)
126
+
127
+ def __setitem__(self, key, lumi):
128
+ """
129
+ Replace the nth lumi from the list (no event count)
130
+ """
131
+ try:
132
+ oldLumi = sorted(self.eventsPerLumi.keys())[key] # Extract the lumi from the sorted list
133
+ del self.eventsPerLumi[oldLumi] # Delete it and add the new one
134
+ except IndexError:
135
+ pass
136
+ self.appendLumi(lumi)
137
+
138
+ def __delitem__(self, key):
139
+ try:
140
+ oldLumi = sorted(self.eventsPerLumi.keys())[key] # Extract the lumi from the sorted list
141
+ del self.eventsPerLumi[oldLumi] # Delete it
142
+ except IndexError:
143
+ pass
144
+
145
+ def __hash__(self):
146
+ """
147
+ Calculate the value of the hash
148
+
149
+ NOTE: Python2 maxint is:
150
+ > python -c 'import sys; print(sys.maxint)'
151
+ 9223372036854775807
152
+ so we cannot use the full range of the hexadecimal hash code because
153
+ it could cause an integer overflow. This is the maximum slice/value we
154
+ can safely use:
155
+ > int(15 * "f", base=16)
156
+ 1152921504606846975
157
+ """
158
+ if isinstance(self.run, (newstr, newbytes)):
159
+ value = encodeUnicodeToBytesConditional(self.run, condition=PY3)
160
+ else:
161
+ value = encodeUnicodeToBytesConditional(str(self.run), condition=PY3)
162
+ hashValue = hashlib.sha1(value)
163
+ # Generate immutable sorted list of lumis
164
+ frozenEvents = str(sorted(listitems(self.eventsPerLumi), key=lambda x: x[0]))
165
+ hashValue.update(encodeUnicodeToBytes(frozenEvents))
166
+ return int(hashValue.hexdigest()[:15], 16)
167
+
168
+ @property
169
+ def lumis(self):
170
+ """
171
+ Property that makes existing uses of myRun.lumis function by returning a list
172
+ """
173
+ return sorted(self.eventsPerLumi.keys())
174
+
175
+ @lumis.setter
176
+ def lumis(self, lumiList):
177
+ """
178
+ Setter to allow for replacement of the lumis with a list or list of tuples
179
+ """
180
+ self.eventsPerLumi = {} # Remove existing dictionary
181
+ for lumi in lumiList:
182
+ if isinstance(lumi, (list, tuple)):
183
+ self.eventsPerLumi[lumi[0]] = lumi[1]
184
+ else:
185
+ self.eventsPerLumi[lumi] = None
186
+
187
+ def extendLumis(self, lumiList):
188
+ """
189
+ Method to replace myRun.lumis.extend() which does not work with the property
190
+ """
191
+ for lumi in lumiList:
192
+ if not isinstance(lumi, (list, tuple)): # comma separated lumi numbers
193
+ self.eventsPerLumi[lumi] = None
194
+ else:
195
+ if isinstance(lumi, list) and not isinstance(lumi[0], tuple): # then it's a plain list
196
+ for l in lumi:
197
+ self.eventsPerLumi[l] = None
198
+ else:
199
+ if isinstance(lumi, tuple): # it's an unpacked list of tuples
200
+ lumi = [(lumi)]
201
+ # it's a list/tuple of tuples
202
+ for tp in lumi:
203
+ if tp[0] in self.eventsPerLumi and self.eventsPerLumi[tp[0]]:
204
+ self.eventsPerLumi[tp[0]] += tp[1] # Already exists, add events
205
+ else: # Doesn't exist or is 0 or None
206
+ self.eventsPerLumi[tp[0]] = tp[1]
207
+
208
+ def appendLumi(self, lumi):
209
+ """
210
+ Method to replace myRun.lumis.append() which does not work with the property
211
+ """
212
+ if isinstance(lumi, (list, tuple)) and self.eventsPerLumi[lumi[0]]: # Already exists, add events
213
+ self.eventsPerLumi[lumi[0]] += lumi[1]
214
+ elif isinstance(lumi, (list, tuple)): # Doesn't exist or is 0 or None
215
+ self.eventsPerLumi[lumi[0]] = lumi[1]
216
+ else: # Just given lumis, not events
217
+ if lumi not in self.eventsPerLumi: # Don't overwrite existing events
218
+ self.eventsPerLumi[lumi] = None
219
+
220
+ def getEventsByLumi(self, lumi):
221
+ """
222
+ getter to select event counts by given lumi
223
+ """
224
+ return self.eventsPerLumi.get(lumi)
225
+
226
+ def json(self):
227
+ """
228
+ _json_
229
+
230
+ Convert to JSON friendly format. Include some information for the
231
+ thunker so that we can convert back.
232
+ """
233
+ return {"Run": self.run, "Lumis": self.eventsPerLumi,
234
+ "thunker_encoded_json": True, "type": "WMCore.DataStructs.Run.Run"}
235
+
236
+ def __to_json__(self, thunker=None):
237
+ """
238
+ __to_json__
239
+
240
+ This is the standard way we JSONize other objects.
241
+ Included here so we have a uniform method.
242
+ """
243
+ return self.json()
244
+
245
+ def __from_json__(self, jsondata, thunker):
246
+ """
247
+ __from_json__
248
+
249
+ Convert JSON data back into a Run object with integer lumi numbers
250
+ """
251
+ self.run = jsondata["Run"]
252
+ self.eventsPerLumi = {}
253
+ for lumi, events in viewitems(jsondata["Lumis"]):
254
+ self.eventsPerLumi[int(lumi)] = events # Make the keys integers again
255
+
256
+ return self
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ _Subscription_
4
+
5
+ workflow + fileset = subscription
6
+ """
7
+
8
+ from builtins import range
9
+ import copy
10
+
11
+ from WMCore.DataStructs.Pickleable import Pickleable
12
+ from WMCore.DataStructs.Fileset import Fileset
13
+
14
+ class Subscription(Pickleable, dict):
15
+ def __init__(self, fileset = None, workflow = None,
16
+ split_algo = "FileBased", type = "Processing"):
17
+ if fileset == None:
18
+ fileset = Fileset()
19
+
20
+ self.setdefault('fileset', fileset)
21
+ self.setdefault('workflow', workflow)
22
+ self.setdefault('type', type)
23
+
24
+ self.setdefault('split_algo', split_algo)
25
+
26
+ self.available = Fileset(name=fileset.name,
27
+ files = fileset.getFiles())
28
+
29
+ self.acquired = Fileset(name='acquired')
30
+ self.completed = Fileset(name='completed')
31
+ self.failed = Fileset(name='failed')
32
+
33
+ def name(self):
34
+ return self.getWorkflow().name.replace(' ', '') + '_' + \
35
+ self.getFileset().name.replace(' ', '')
36
+
37
+ def getWorkflow(self):
38
+ return self["workflow"]
39
+
40
+ def workflowName(self):
41
+ if self["workflow"] == None:
42
+ return "Unknown"
43
+ return self["workflow"].name
44
+
45
+ def workflowType(self):
46
+ if self["workflow"] == None:
47
+ return "Unknown"
48
+ return self["workflow"].wfType
49
+
50
+ def taskName(self):
51
+ if self['workflow'] == None:
52
+ return "Unknown"
53
+ return self['workflow'].task
54
+
55
+ def owner(self):
56
+ if self['workflow'] == None:
57
+ return 'Unknown'
58
+ return self['workflow'].owner
59
+
60
+ def getFileset(self):
61
+ return self['fileset']
62
+
63
+ def acquireFiles(self, files = [], size=1):
64
+ """
65
+ Return the files acquired
66
+ """
67
+ self.acquired.commit()
68
+ self.available.commit()
69
+ self.failed.commit()
70
+ self.completed.commit()
71
+ retval = []
72
+ if len(files):
73
+ for i in files:
74
+ # Check each set, instead of elif, just in case something has
75
+ # got out of synch
76
+ if i in self.available.files:
77
+ self.available.files.remove(i)
78
+ if i in self.failed.files:
79
+ self.failed.files.remove(i)
80
+ if i in self.completed.files:
81
+ self.completed.files.remove(i)
82
+ self.acquired.addFile(i)
83
+ else:
84
+ if len(self.available.files) < size or size == 0:
85
+ size = len(self.available.files)
86
+ for i in range(size):
87
+ self.acquired.addFile(self.available.files.pop())
88
+
89
+ return self.acquired.listNewFiles()
90
+
91
+ def completeFiles(self, files):
92
+ """
93
+ Return the number of files complete
94
+ """
95
+ self.acquired.commit()
96
+ self.available.commit()
97
+ self.failed.commit()
98
+ self.completed.commit()
99
+ for i in files:
100
+ # Check each set, instead of elif, just in case something has
101
+ # got out of synch
102
+ if i in self.available.files:
103
+ self.available.files.remove(i)
104
+ if i in self.failed.files:
105
+ self.failed.files.remove(i)
106
+ if i in self.acquired.files:
107
+ self.acquired.files.remove(i)
108
+ self.completed.addFile(i)
109
+
110
+ def failFiles(self, files):
111
+ """
112
+ Return the number of files failed
113
+ """
114
+ self.acquired.commit()
115
+ self.available.commit()
116
+ self.failed.commit()
117
+ self.completed.commit()
118
+ for i in files:
119
+ # Check each set, instead of elif, just in case something has
120
+ # got out of synch
121
+ if i in self.available.files:
122
+ self.available.files.remove(i)
123
+ if i in self.completed.files:
124
+ self.completed.files.remove(i)
125
+ if i in self.acquired.files:
126
+ self.acquired.files.remove(i)
127
+ self.failed.addFile(i)
128
+
129
+ def filesOfStatus(self, status=None, doingJobSplitting = False):
130
+ """
131
+ _filesOfStatus_
132
+
133
+ Return a Set of File objects that are associated with the subscription
134
+ and have a particular status.
135
+ """
136
+ status = status.title()
137
+ if status == 'Available':
138
+ return self.available.getFiles(type='set') - \
139
+ (self.acquiredFiles() | self.completedFiles() | self.failedFiles())
140
+ elif status == 'Acquired':
141
+ return self.acquired.getFiles(type='set')
142
+ elif status == 'Completed':
143
+ return self.completed.getFiles(type='set')
144
+ elif status == 'Failed':
145
+ return self.failed.getFiles(type='set')
146
+
147
+ def availableFiles(self, limit = None, doingJobSplitting = False):
148
+ """
149
+ _availableFiles_
150
+
151
+ Return a Set of files that are available for processing
152
+ (e.g. not already in use)
153
+ """
154
+ if limit:
155
+ return list(self.filesOfStatus(status = "Available", doingJobSplitting = doingJobSplitting))[:limit]
156
+ else:
157
+ return self.filesOfStatus(status = "Available", doingJobSplitting = doingJobSplitting)
158
+
159
+ def acquiredFiles(self):
160
+ """
161
+ Set of files marked as acquired.
162
+ """
163
+ return self.filesOfStatus(status = "Acquired")
164
+
165
+ def completedFiles(self):
166
+ """
167
+ Set of files marked as completed.
168
+ """
169
+ return self.filesOfStatus(status = "Completed")
170
+
171
+ def failedFiles(self):
172
+ """
173
+ Set of files marked as failed.
174
+ """
175
+ return self.filesOfStatus(status = "Failed")
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ _WMObject_
4
+
5
+ Helper class that other objects should inherit from
6
+
7
+ """
8
+ from builtins import object
9
+ __all__ = []
10
+
11
+
12
+
13
+
14
+ class WMObject(object):
15
+ """
16
+ Helper class that other objects should inherit from
17
+ """
18
+ def __init__(self, config = {}):
19
+ #Config is a WMCore.Configuration
20
+ self.config = config
21
+
22
+ def makelist(self, thelist):
23
+ """
24
+ Simple method to ensure thelist is a list
25
+ """
26
+ if isinstance(thelist, set):
27
+ thelist = list(thelist)
28
+ elif not isinstance(thelist, list):
29
+ thelist = [thelist]
30
+ return thelist
31
+
32
+ def makeset(self, theset):
33
+ """
34
+ Simple method to ensure theset is a set
35
+ """
36
+ if not isinstance(theset, set):
37
+ theset = set(self.makelist(theset))
38
+ return theset
39
+
40
+ def flatten(self, list):
41
+ """
42
+ If a list has only one element return just that element, otherwise
43
+ return the original list
44
+ """
45
+ if len(list) == 1:
46
+ return list[0]
47
+ return list
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ _WorkUnit_
4
+
5
+ Data object that contains details for a single work unit
6
+
7
+ """
8
+
9
+ from __future__ import absolute_import, division, print_function
10
+
11
+ from future.utils import listitems
12
+
13
+ import sys
14
+ import hashlib
15
+ import time
16
+ from functools import total_ordering
17
+
18
+ from Utils.Utilities import encodeUnicodeToBytes
19
+ from WMCore.DataStructs.WMObject import WMObject
20
+
21
+
22
+ @total_ordering
23
+ class WorkUnit(WMObject, dict):
24
+ """
25
+ _WorkUnit_
26
+ Data object that contains details for a single work unit
27
+ corresponding to tables workunit and frl_workunit_assoc
28
+ """
29
+
30
+ fieldsToCopy = ['taskid', 'retry_count', 'last_unit_count', 'last_submit_time', 'status', 'firstevent',
31
+ 'lastevent', 'fileid']
32
+ fieldsForInfo = fieldsToCopy + ['run_lumi']
33
+
34
+ def __init__(self, taskID=None, retryCount=0, lastUnitCount=None, lastSubmitTime=int(time.time()),
35
+ status=0, firstEvent=1, lastEvent=sys.maxsize, fileid=None, runLumi=None):
36
+ super(WorkUnit, self).__init__(self)
37
+ self.setdefault('taskid', taskID)
38
+ self.setdefault('retry_count', retryCount)
39
+ self.setdefault('last_unit_count', lastUnitCount)
40
+ self.setdefault('last_submit_time', lastSubmitTime)
41
+ self.setdefault('status', status)
42
+
43
+ self.setdefault('firstevent', firstEvent)
44
+ self.setdefault('lastevent', lastEvent)
45
+ self.setdefault('fileid', fileid)
46
+ self.setdefault('run_lumi', runLumi)
47
+
48
+ def __lt__(self, rhs):
49
+ """
50
+ Compare work units in task id, run, lumi, first event, last event
51
+ """
52
+
53
+ if self['taskid'] != rhs['taskid']:
54
+ return self['taskid'] < rhs['taskid']
55
+ if self['run_lumi'].run != rhs['run_lumi'].run:
56
+ return self['run_lumi'].run < rhs['run_lumi'].run
57
+ if self['run_lumi'].lumis != rhs['run_lumi'].lumis:
58
+ return self['run_lumi'].lumis < rhs['run_lumi'].lumis
59
+ if self['first_event'] != rhs['first_event']:
60
+ return self['first_event'] < rhs['first_event']
61
+ return self['last_event'] < rhs['last_event']
62
+
63
+ def __eq__(self, rhs):
64
+ """
65
+ Work unit is equal if it has the same task, run, and lumi
66
+ """
67
+
68
+ return (self['taskid'] == rhs['taskid'] and self['run_lumi'].run == self['run_lumi'].run and
69
+ self['run_lumi'].lumis == self['run_lumi'].lumis and self['firstevent'] == rhs['firstevent'] and
70
+ self['lastevent'] == rhs['lastevent'])
71
+
72
+ def __hash__(self):
73
+ """
74
+ Hash function for this dict.
75
+ """
76
+ # Generate an immutable sorted string representing this object
77
+ # NOTE: the run object needs to be hashed
78
+ immutableSelf = []
79
+ for keyName in sorted(self):
80
+ if keyName == "run_lumi":
81
+ immutableSelf.append((keyName, hash(self[keyName])))
82
+ else:
83
+ immutableSelf.append((keyName, self[keyName]))
84
+ hashValue = hashlib.sha1(encodeUnicodeToBytes(str(immutableSelf)))
85
+ return int(hashValue.hexdigest()[:15], 16)
86
+
87
+ def json(self, thunker=None):
88
+ """
89
+ _json_
90
+
91
+ Serialize the object. Only copy select fields and construct one new field.
92
+ """
93
+
94
+ jsonDict = {k: self[k] for k in WorkUnit.fieldsToCopy}
95
+ jsonDict["run_lumi"] = {"run_number": self['run_lumi'].run, "lumis": self['run_lumi'].lumis}
96
+
97
+ return jsonDict
98
+
99
+ def __to_json__(self, thunker=None):
100
+ """
101
+ __to_json__
102
+
103
+ This is the standard way we jsonize other objects.
104
+ Included here so we have a uniform method.
105
+ """
106
+ return self.json(thunker)
107
+
108
+ def getInfo(self):
109
+ """
110
+ Returns: tuple of parameters for the work unit
111
+ """
112
+ return tuple(self[x] for x in WorkUnit.fieldsForInfo)
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ _Workflow_
4
+
5
+ A class that describes some work to be undertaken on some files
6
+ """
7
+
8
+ from builtins import str
9
+ from WMCore.DataStructs.Pickleable import Pickleable
10
+
11
+ class Workflow(Pickleable):
12
+ def __init__(self, spec = None, owner = "unknown", dn = "unknown",
13
+ group = "unknown", owner_vogroup = "unknown",
14
+ owner_vorole = "unknown", name = None, task = None,
15
+ wfType = None, priority = None):
16
+ self.spec = spec
17
+ self.name = name
18
+ # person making the request
19
+ self.owner = owner
20
+ self.dn = dn
21
+ self.vogroup = owner_vogroup
22
+ self.vorole = owner_vorole
23
+ self.group = group
24
+ # task is the name of the task within the Workload
25
+ self.task = task
26
+ self.wfType = wfType
27
+ self.outputMap = {}
28
+ self.priority = priority or 0
29
+
30
+ def addOutput(self, outputIdentifier, outputFileset,
31
+ mergedOutputFileset = None):
32
+ """
33
+ _addOutput_
34
+
35
+ Associate an output of this workflow with a particular fileset.
36
+ """
37
+ mappingDict = {"output_fileset": outputFileset,
38
+ "merged_output_fileset": mergedOutputFileset}
39
+
40
+ if outputIdentifier in self.outputMap:
41
+ self.outputMap[outputIdentifier].append(mappingDict)
42
+ else:
43
+ self.outputMap[outputIdentifier] = [mappingDict]
44
+
45
+ return
46
+
47
+ def __str__(self):
48
+ """
49
+ __str__
50
+
51
+ Print out some useful info just because
52
+ this does not inherit from dict.
53
+ """
54
+
55
+ d = {'id': self.id, 'spec': self.spec, 'name': self.name,
56
+ 'owner': self.owner, 'task': self.task,
57
+ 'vogroup': self.vogroup, 'vorole': self.vorole,
58
+ 'group': self.group, 'wfType': self.wfType}
59
+
60
+ return str(d)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ _DataStructs_
4
+
5
+ A set of base objects to be used/inherited elsewhere
6
+
7
+ """
8
+ __all__ = []