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
Utils/ProcessStats.py ADDED
@@ -0,0 +1,194 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ File : ProcessStats.py
5
+ Author : Valentin Kuznetsov <vkuznet AT gmail dot com>
6
+ Description: This module provide ability to get detailed information about
7
+ certain UNIX process, referred by PID. It is based on psutil and threading
8
+ python modules. It can be used in any web/data-server to get live status
9
+ about the running server. Here is an example
10
+
11
+ .. doctest:
12
+
13
+ from Utils.procstats import status threadStack
14
+
15
+ class SomeServer(object):
16
+ def __init__(self):
17
+ self.time0 = time.time()
18
+ def status(self):
19
+ sdict = {'server': processStatus()}
20
+ sdict['server'].update({'uptime': time.time()-self.time0})
21
+ sdict.update(threadStack())
22
+ return sdict
23
+
24
+ The exposed status endpoint will return a json dictionary containing server
25
+ upteima and cpu/mem/threads information.
26
+ """
27
+
28
+ # system modules
29
+ import os
30
+ import sys
31
+ import json
32
+ import time
33
+ import argparse
34
+ import threading
35
+ import traceback
36
+
37
+ try:
38
+ import psutil
39
+ except ImportError:
40
+ pass
41
+
42
+ def _baseProcessStatusFormat(pid=None):
43
+ if not pid:
44
+ pid = os.getpid()
45
+ ttime = time.localtime()
46
+ tstamp = time.strftime('%d/%b/%Y:%H:%M:%S', ttime)
47
+ return {'pid': pid, 'timestamp': tstamp, 'time': time.time()}
48
+
49
+ def processStatus(pid=None):
50
+ "Return status of the process in a dictionary format"
51
+
52
+ pdict = _baseProcessStatusFormat(pid)
53
+ if 'psutil' not in sys.modules:
54
+ return pdict
55
+ proc = psutil.Process(pid)
56
+ pdict.update(proc.as_dict())
57
+ return pdict
58
+
59
+ def processStatusDict(pid=None):
60
+ "Return status of the process in a dictionary format"
61
+ pdict = _baseProcessStatusFormat(pid)
62
+ if 'psutil' not in sys.modules:
63
+ return pdict
64
+ proc = psutil.Process(pid)
65
+ pdict.update({"cpu_times": dict(proc.cpu_times()._asdict())})
66
+ pdict.update({"cpu_percent": proc.cpu_percent(interval=1.0)})
67
+ pdict.update({"cpu_num": proc.cpu_num()})
68
+ pdict.update({"memory_full_info": dict(proc.memory_full_info()._asdict())})
69
+ pdict.update({"memory_percent": proc.memory_percent()})
70
+ return pdict
71
+
72
+ def threadStack():
73
+ """
74
+ Return context of all threads in dictionary format where individual
75
+ thread information stored in its own dicts and all threads are groupped
76
+ into threads list. Code based on example from StackOverflow:
77
+ http://stackoverflow.com/questions/132058/showing-the-stack-trace-from-a-running-python-application
78
+ """
79
+ tdict = {}
80
+ id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
81
+ threads = []
82
+ for tid, stack in list(sys._current_frames().items()):
83
+ tdict = {"thead": id2name.get(tid, ""), "thead_id": tid}
84
+ stacklist = []
85
+ for filename, lineno, name, line in traceback.extract_stack(stack):
86
+ sdict = dict(filename=filename, line_number=lineno, name=name, line=line)
87
+ stacklist.append(sdict)
88
+ tdict.update({"stack": stacklist})
89
+ threads.append(tdict)
90
+ return dict(threads=threads)
91
+
92
+ def processThreadsInfo(pid):
93
+ """
94
+ Provides information about process and its threads using psutils
95
+ :param pid: process PID, string
96
+ :return: dictionary statistics about process and threads
97
+ """
98
+ try:
99
+ process = psutil.Process(pid)
100
+
101
+ # Get overall process details
102
+ process_info = {
103
+ "process_name": process.name(),
104
+ "pid": process.pid,
105
+ "status": process.status(),
106
+ "ppid": process.ppid(), # Parent Process ID
107
+ "is_running":process.is_running(), # NOTE: Zombie processes could also be reported as running
108
+ "cmdline": process.cmdline(), # Full command-line arguments
109
+ "cpu_usage_percent": process.cpu_percent(interval=1.0), # CPU usage in percentage
110
+ "memory_usage_percent": process.memory_percent(), # RAM usage in percentage
111
+ "memory_rss": process.memory_info().rss, # Resident Set Size (bytes)
112
+ "num_open_files": len(process.open_files()), # Number of open file descriptors
113
+ "num_connections": len(process.connections()), # Number of active connections
114
+ "threads": []
115
+ }
116
+
117
+ # Iterate over threads to get per-thread details
118
+ for thread in process.threads():
119
+ if str(pid) == str(thread.id):
120
+ continue
121
+ thread_id = thread.id
122
+
123
+ thread_info = {
124
+ "thread_id": thread_id,
125
+ "user_time": thread.user_time, # CPU time spent in user mode
126
+ "system_time": thread.system_time, # CPU time spent in system mode
127
+ "cpu_usage_percent": None,
128
+ "memory_usage_bytes": None,
129
+ "num_open_files": None,
130
+ "num_connections": None,
131
+ "is_running":process.is_running(), # NOTE: Zombie processes could also be reported as running
132
+ "status": "unknown",
133
+ "name": "thread"
134
+ }
135
+ if str(pid) == str(thread_id):
136
+ thread_info['name'] = "process"
137
+
138
+ # Try getting thread status
139
+ try:
140
+ thread_status = psutil.Process(thread_id).status()
141
+ thread_info["status"] = thread_status
142
+ except psutil.NoSuchProcess:
143
+ thread_info["status"] = psutil.STATUS_ZOMBIE
144
+
145
+ # Try getting per-thread CPU usage
146
+ try:
147
+ thread_info["cpu_usage_percent"] = psutil.Process(thread_id).cpu_percent(interval=1.0)
148
+ except Exception:
149
+ thread_info["cpu_usage_percent"] = "N/A"
150
+
151
+ # Try getting per-thread memory usage
152
+ try:
153
+ thread_info["memory_usage_bytes"] = psutil.Process(thread_id).memory_info().rss
154
+ except Exception:
155
+ thread_info["memory_usage_bytes"] = "N/A"
156
+
157
+ # Try getting per-thread open file descriptors
158
+ try:
159
+ thread_info["num_open_files"] = len(psutil.Process(thread_id).open_files())
160
+ except Exception:
161
+ thread_info["num_open_files"] = "N/A"
162
+
163
+ # Try getting per-thread open connections
164
+ try:
165
+ thread_info["num_connections"] = len(psutil.Process(thread_id).connections())
166
+ except Exception:
167
+ thread_info["num_connections"] = "N/A"
168
+
169
+ # Append to process_info
170
+ process_info["threads"].append(thread_info)
171
+
172
+ return process_info
173
+ except psutil.NoSuchProcess:
174
+ return {"error": f"No process found with PID {pid}"}
175
+ except Exception as e:
176
+ return {"error": str(e)}
177
+
178
+ def main():
179
+ "Main function to use this module as a stand-along script."
180
+ parser = argparse.ArgumentParser(prog='PROG')
181
+ parser.add_argument("--pid", action="store", dest="pid", help="process id")
182
+ opts = parser.parse_args()
183
+
184
+ pdict = processStatus(int(opts.pid))
185
+ pdict.update(threadStack())
186
+ print(f"Process status for {opts.pid}")
187
+ print(json.dumps(pdict, indent=4))
188
+
189
+ processInfo = processThreadsInfo(int(opts.pid))
190
+ print(f"Process/threads status for {opts.pid}")
191
+ print(json.dumps(processInfo, indent=4))
192
+
193
+ if __name__ == '__main__':
194
+ main()
Utils/PythonVersion.py ADDED
@@ -0,0 +1,17 @@
1
+ """
2
+ Easily get the version of the python interpreter at runtime
3
+ """
4
+
5
+ # Jenkins CI
6
+
7
+ import sys
8
+ import pickle
9
+
10
+ PY3 = sys.version_info[0] == 3
11
+ PY2 = sys.version_info[0] == 2
12
+
13
+ # We need to keep compatibility between multiple python versions
14
+ # Further details at: https://github.com/dmwm/WMCore/pull/10726
15
+ # For PY2: set highest protocol to 2
16
+ # For PY3: set highest protocol to 4 (compatible with python3.6 and python3.8)
17
+ HIGHEST_PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL if PY2 else 4
Utils/Signals.py ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env python
2
+ #-*- coding: utf-8 -*-
3
+ #pylint: disable=
4
+ """
5
+ File : Signals.py
6
+ Author : Valentin Kuznetsov <vkuznet AT gmail dot com>
7
+ Description: This module provide set of hooks to running program
8
+ The dumpthreads callback function will be called every time when
9
+ running program will receive SIGUSR1 signal. E.g., in unix shell
10
+ just do
11
+ shell# kill -s SIGUSR1 <pid>
12
+ """
13
+
14
+ # system modules
15
+ import sys
16
+ import signal
17
+ import threading
18
+ import traceback
19
+
20
+ def dumpthreads(isignal, iframe):
21
+ """
22
+ Dump context of all threads upon given signal
23
+ http://stackoverflow.com/questions/132058/showing-the-stack-trace-from-a-running-python-application
24
+ """
25
+ print("DAS stack, signal=%s, frame=%s" % (isignal, iframe))
26
+ id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
27
+ code = []
28
+ for tid, stack in list(sys._current_frames().items()):
29
+ code.append("\n# Thread: %s(%d)" % (id2name.get(tid,""), tid))
30
+ for filename, lineno, name, line in traceback.extract_stack(stack):
31
+ code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
32
+ if line:
33
+ code.append(" %s" % (line.strip()))
34
+ print("\n".join(code))
35
+
36
+ signal.signal(signal.SIGUSR1, dumpthreads)
@@ -0,0 +1,27 @@
1
+ #! /usr/bin/env python
2
+
3
+ import contextlib
4
+ import os
5
+
6
+
7
+ @contextlib.contextmanager
8
+ def tmpEnv(**environ):
9
+ """
10
+ Temporarily set the process environment variables.
11
+
12
+ >>> with tmpEnv(PLUGINS_DIR=u'test/plugins'):
13
+ ... "PLUGINS_DIR" in os.environ
14
+ True
15
+
16
+ >>> "PLUGINS_DIR" in os.environ
17
+ False
18
+
19
+ :param environ: Environment variables to set
20
+ """
21
+ oldEnviron = dict(os.environ)
22
+ os.environ.update(environ)
23
+ try:
24
+ yield
25
+ finally:
26
+ os.environ.clear()
27
+ os.environ.update(oldEnviron)
Utils/Throttled.py ADDED
@@ -0,0 +1,227 @@
1
+ # pylint: disable-msg=C0103,C0111,W0212
2
+ """
3
+ Throttled module defines necessary classes to throttle context.
4
+ Should be used in Web server APIs which wants to throttle clients.
5
+
6
+ The counter based approach, implemented in _ThrottleCounter class,
7
+ defines throttling on total number of user access to the underlying
8
+ app. But its counter depends on time execution of the API.
9
+
10
+ The time based approach, implemented in _ThrottleTimeCount class,
11
+ count total number of user accesses within specified time interval
12
+ regardless of time execution of the underlying API(s).
13
+
14
+ Here is an example how to use this module/classes:
15
+
16
+ # counter based throttline
17
+
18
+ from Utils.Throttling import UserThrottle
19
+ thr = UserThrottle(limit=5) # adjust threshold limit here
20
+ @thr.make_throttled()
21
+ def api():
22
+ # define your api logic here
23
+
24
+ # time based throttling
25
+
26
+ from Utils.Throttling import UserThrottleTime
27
+ thr = UserThrottleTime(limit=5) # adjust threshold limit here
28
+ @thr.make_throttled(trange=2) # adjust trange (in sec) here
29
+ def api():
30
+ # define your api logic here
31
+
32
+ """
33
+
34
+
35
+ # standard modules
36
+ import time
37
+ from builtins import object
38
+ import logging
39
+ import threading
40
+
41
+ # cherrypy modules
42
+ import cherrypy
43
+
44
+
45
+ class _ThrottleCounter(object):
46
+ """
47
+ _ThrottleCounter class defines throttle parameter and
48
+ enter/exit methods to work with `with` context.
49
+ """
50
+
51
+ def __init__(self, throttle, user, debug=False):
52
+ self.throttle = throttle
53
+ self.user = user
54
+ if debug:
55
+ self.throttle.logger.setLevel(logging.DEBUG)
56
+
57
+ def __enter__(self):
58
+ "Define enter method for `with` context"
59
+ ctr = self.throttle._incUser(self.user)
60
+ msg = "Entering throttled function with counter %d for user %s" \
61
+ % (ctr, self.user)
62
+ self.throttle.logger.debug(msg)
63
+ if ctr > self.throttle.getLimit():
64
+ msg = "The current number of active operations for this resource"
65
+ msg += " exceeds the limit of %d for user %s" \
66
+ % (self.throttle.getLimit(), self.user)
67
+ raise cherrypy.HTTPError("429 Too Many Requests", msg)
68
+
69
+ def __exit__(self, exc_type, exc_value, exc_traceback):
70
+ "Define exit method for `with` context"
71
+ ctr = self.throttle._decUser(self.user)
72
+ msg = "Exiting throttled function with counter %d for user %s" \
73
+ % (ctr, self.user)
74
+ self.throttle.logger.debug(msg)
75
+
76
+ class _ThrottleTimeCounter(object):
77
+ """
78
+ _ThrottleTimeCounter class defines time range throttled mechanism
79
+ """
80
+
81
+ def __init__(self, throttle, user, trange):
82
+ self.throttle = throttle
83
+ self.user = user
84
+ self.trange = trange
85
+
86
+ def __enter__(self):
87
+ "Define enter method for `with` context"
88
+ ctr = self.throttle._incUser(self.user, self.trange)
89
+ if ctr > self.throttle.getLimit():
90
+ self.throttle._decUser(self.user)
91
+ msg = "The current number of active operations for this resource"
92
+ msg += " exceeds the limit of %d for user %s in last %s sec" \
93
+ % (self.throttle.getLimit(), self.user, self.trange)
94
+ raise cherrypy.HTTPError("429 Too Many Requests", msg)
95
+
96
+ def __exit__(self, exc_type, exc_value, exc_traceback):
97
+ "Define exit method for `with` context"
98
+ pass
99
+
100
+
101
+ class UserThrottleTime(object):
102
+ """
103
+ UserThrottle class defines how to handle throttle time range based mechanism.
104
+ """
105
+
106
+ def __init__(self, limit=3):
107
+ self.lock = threading.Lock()
108
+ self.users = {}
109
+ self.users_time = {}
110
+ self.limit = limit
111
+
112
+ def getLimit(self):
113
+ "Return throttle limit"
114
+ return self.limit
115
+
116
+ def throttleContext(self, user, trange=60):
117
+ """
118
+ Define throttle context via _ThrottleTimeCounter class
119
+ which will count number of requests given user made in trange
120
+ :param user: user name
121
+ :param trange: time range while keep user access history
122
+ """
123
+ return _ThrottleTimeCounter(self, user, trange)
124
+
125
+ def make_throttled(self, trange=60):
126
+ "decorator for throttled context"
127
+ def throttled_decorator(fn):
128
+ def throttled_wrapped_function(*args, **kw):
129
+ username = cherrypy.request.user.get('login', 'Unknown') \
130
+ if hasattr(cherrypy.request, 'user') else 'Unknown'
131
+ with self.throttleContext(username, trange):
132
+ return fn(*args, **kw)
133
+ return throttled_wrapped_function
134
+ return throttled_decorator
135
+
136
+ def reset(self, user):
137
+ "Reset user activities, i.e. access counter and last time of access"
138
+ self.users[user] = 0
139
+ self.users_time[user] = time.time()
140
+
141
+ def _incUser(self, user, trange=60):
142
+ "increment user count"
143
+ with self.lock:
144
+ self.users.setdefault(user, 0)
145
+ last_time = self.users_time.setdefault(user, time.time())
146
+ # increase counter within our trange
147
+ if abs(time.time()-last_time) < trange:
148
+ self.users[user] += 1
149
+ else:
150
+ self.reset(user)
151
+ return self.users[user]
152
+
153
+ def _decUser(self, user, trange=60):
154
+ "decrecrement user count"
155
+ with self.lock:
156
+ # decrease counter outside of our trange
157
+ last_time = self.users_time[user]
158
+ if abs(time.time()-last_time) < trange:
159
+ # gradually decrease user counter based on his/her elapsed time
160
+ step = int(trange - abs(time.time()-last_time))
161
+ self.users[user] -= step
162
+ if self.users[user] < 0:
163
+ self.reset(user)
164
+ else:
165
+ self.reset(user)
166
+
167
+ class UserThrottle(object):
168
+ """
169
+ UserThrottle class defines throttle counter based mechanism.
170
+ """
171
+
172
+ def __init__(self, limit=3):
173
+ self.lock = threading.Lock()
174
+ self.tls = threading.local()
175
+ self.users = {}
176
+ self.limit = limit
177
+ self.logger = logging.getLogger("WMCore.UserThrottle")
178
+
179
+ def getLimit(self):
180
+ "Return throttle limit"
181
+ return self.limit
182
+
183
+ def throttleContext(self, user, debug=False):
184
+ "defint throttle context"
185
+ self.users.setdefault(user, 0)
186
+ return _ThrottleCounter(self, user, debug)
187
+
188
+ def make_throttled(self, debug=False):
189
+ """
190
+ decorator for throttled context
191
+ """
192
+ def throttled_decorator(fn):
193
+ """
194
+ A decorator
195
+ """
196
+ def throttled_wrapped_function(*args, **kw):
197
+ """
198
+ A wrapped function.
199
+ """
200
+ username = cherrypy.request.user.get('login', 'Unknown') \
201
+ if hasattr(cherrypy.request, 'user') else 'Unknown'
202
+ with self.throttleContext(username, debug):
203
+ return fn(*args, **kw)
204
+ return throttled_wrapped_function
205
+ return throttled_decorator
206
+
207
+ def _incUser(self, user):
208
+ "increment user count"
209
+ retval = 0
210
+ with self.lock:
211
+ retval = self.users[user]
212
+ if getattr(self.tls, 'count', None) is None:
213
+ self.tls.count = 0
214
+ self.tls.count += 1
215
+ if self.tls.count == 1:
216
+ self.users[user] = retval + 1
217
+ return retval
218
+
219
+ def _decUser(self, user):
220
+ "decrecrement user count"
221
+ retval = 0
222
+ with self.lock:
223
+ retval = self.users[user]
224
+ self.tls.count -= 1
225
+ if self.tls.count == 0:
226
+ self.users[user] = retval - 1
227
+ return retval
Utils/Timers.py ADDED
@@ -0,0 +1,130 @@
1
+ #!/bin/env python
2
+ """
3
+ Utilities related to timing and performance testing
4
+ """
5
+
6
+ from builtins import object
7
+ import logging
8
+ import time
9
+ import calendar
10
+ from datetime import tzinfo, timedelta
11
+
12
+
13
+ def gmtimeSeconds():
14
+ """
15
+ Return GMT time in seconds
16
+ """
17
+ return int(time.mktime(time.gmtime()))
18
+
19
+
20
+ def encodeTimestamp(secs):
21
+ """
22
+ Encode second since epoch to a string GMT timezone representation
23
+ :param secs: input timestamp value (either int or float) in seconds since epoch
24
+
25
+ :return: time string in GMT timezone representation
26
+ """
27
+ if not isinstance(secs, (int, float)):
28
+ raise Exception("Wrong input, should be seconds since epoch either int or float value")
29
+ return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(int(secs)))
30
+
31
+
32
+ def decodeTimestamp(timeString):
33
+ """
34
+ Decode timestamps in provided document
35
+ :param timeString: timestamp string represention in GMT timezone, see encodeTimestamp
36
+
37
+ :return: seconds since ecouch in GMT timezone
38
+ """
39
+ if not isinstance(timeString, str):
40
+ raise Exception("Wrong input, should be time string in GMT timezone representation")
41
+ return calendar.timegm(time.strptime(timeString, "%Y-%m-%dT%H:%M:%SZ"))
42
+
43
+
44
+ def timeFunction(func):
45
+ """
46
+ source: https://www.andreas-jung.com/contents/a-python-decorator-for-measuring-the-execution-time-of-methods
47
+
48
+ Decorator function to measure how long a method/function takes to run
49
+ It returns a tuple with:
50
+ * wall clock time spent
51
+ * returned result of the function
52
+ * the function name
53
+ """
54
+
55
+ def wrapper(*arg, **kw):
56
+ t1 = time.time()
57
+ res = func(*arg, **kw)
58
+ t2 = time.time()
59
+ return round((t2 - t1), 4), res, func.__name__
60
+
61
+ return wrapper
62
+
63
+
64
+ class CodeTimer(object):
65
+ """
66
+ A context manager for timing function calls.
67
+ Adapted from https://www.blog.pythonlibrary.org/2016/05/24/python-101-an-intro-to-benchmarking-your-code/
68
+
69
+ Use like
70
+
71
+ with CodeTimer(label='Doing something'):
72
+ do_something()
73
+ """
74
+
75
+ def __init__(self, label='The function', logger=None):
76
+ self.start = time.time()
77
+ self.label = label
78
+ self.logger = logger or logging.getLogger()
79
+
80
+ def __enter__(self):
81
+ return self
82
+
83
+ def __exit__(self, exc_type, exc_val, exc_tb):
84
+ end = time.time()
85
+ runtime = round((end - self.start), 3)
86
+ self.logger.info(f"{self.label} took {runtime} seconds to complete")
87
+
88
+
89
+ class LocalTimezone(tzinfo):
90
+ """
91
+ A required python 2 class to determine current timezone for formatting rfc3339 timestamps
92
+ Required for sending alerts to the MONIT AlertManager
93
+ Can be removed once WMCore starts using python3
94
+
95
+ Details of class can be found at: https://docs.python.org/2/library/datetime.html#tzinfo-objects
96
+ """
97
+
98
+ def __init__(self):
99
+ super(LocalTimezone, self).__init__()
100
+ self.ZERO = timedelta(0)
101
+ self.STDOFFSET = timedelta(seconds=-time.timezone)
102
+ if time.daylight:
103
+ self.DSTOFFSET = timedelta(seconds=-time.altzone)
104
+ else:
105
+ self.DSTOFFSET = self.STDOFFSET
106
+
107
+ self.DSTDIFF = self.DSTOFFSET - self.STDOFFSET
108
+
109
+ def utcoffset(self, dt):
110
+ if self._isdst(dt):
111
+ return self.DSTOFFSET
112
+ else:
113
+ return self.STDOFFSET
114
+
115
+ def dst(self, dt):
116
+ if self._isdst(dt):
117
+ return self.DSTDIFF
118
+ else:
119
+ return self.ZERO
120
+
121
+ def tzname(self, dt):
122
+ return time.tzname[self._isdst(dt)]
123
+
124
+ def _isdst(self, dt):
125
+ tt = (dt.year, dt.month, dt.day,
126
+ dt.hour, dt.minute, dt.second,
127
+ dt.weekday(), 0, 0)
128
+ stamp = time.mktime(tt)
129
+ tt = time.localtime(stamp)
130
+ return tt.tm_isdst > 0