genie 0.1

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 (313) hide show
  1. data/genie-0.1.gem +0 -0
  2. data/genie-0.1/docs/classes/BasicCommand.html +249 -0
  3. data/genie-0.1/docs/classes/BasicCommand.src/M000070.html +18 -0
  4. data/genie-0.1/docs/classes/BasicCommand.src/M000071.html +18 -0
  5. data/genie-0.1/docs/classes/BasicCommand.src/M000072.html +18 -0
  6. data/genie-0.1/docs/classes/BasicCommand.src/M000073.html +18 -0
  7. data/genie-0.1/docs/classes/BasicCommand.src/M000074.html +16 -0
  8. data/genie-0.1/docs/classes/Command.html +277 -0
  9. data/genie-0.1/docs/classes/Command.src/M000052.html +20 -0
  10. data/genie-0.1/docs/classes/Command.src/M000053.html +18 -0
  11. data/genie-0.1/docs/classes/Command.src/M000054.html +20 -0
  12. data/genie-0.1/docs/classes/Command.src/M000055.html +20 -0
  13. data/genie-0.1/docs/classes/Command.src/M000056.html +18 -0
  14. data/genie-0.1/docs/classes/Command.src/M000057.html +18 -0
  15. data/genie-0.1/docs/classes/Command.src/M000058.html +23 -0
  16. data/genie-0.1/docs/classes/CommandMetainfo.html +362 -0
  17. data/genie-0.1/docs/classes/CommandMetainfo.src/M000042.html +18 -0
  18. data/genie-0.1/docs/classes/CommandMetainfo.src/M000043.html +18 -0
  19. data/genie-0.1/docs/classes/CommandMetainfo.src/M000044.html +19 -0
  20. data/genie-0.1/docs/classes/CommandMetainfo.src/M000045.html +25 -0
  21. data/genie-0.1/docs/classes/CommandMetainfo.src/M000046.html +21 -0
  22. data/genie-0.1/docs/classes/CommandMetainfo.src/M000047.html +21 -0
  23. data/genie-0.1/docs/classes/CompoundResult.html +359 -0
  24. data/genie-0.1/docs/classes/CompoundResult.src/M000075.html +18 -0
  25. data/genie-0.1/docs/classes/CompoundResult.src/M000076.html +18 -0
  26. data/genie-0.1/docs/classes/CompoundResult.src/M000078.html +18 -0
  27. data/genie-0.1/docs/classes/CompoundResult.src/M000079.html +18 -0
  28. data/genie-0.1/docs/classes/CompoundResult.src/M000080.html +18 -0
  29. data/genie-0.1/docs/classes/CompoundResult.src/M000082.html +18 -0
  30. data/genie-0.1/docs/classes/CompoundResult.src/M000084.html +20 -0
  31. data/genie-0.1/docs/classes/CompoundResult.src/M000085.html +18 -0
  32. data/genie-0.1/docs/classes/CompoundResult.src/M000086.html +18 -0
  33. data/genie-0.1/docs/classes/CompoundResult.src/M000087.html +20 -0
  34. data/genie-0.1/docs/classes/EntryProcessor.html +223 -0
  35. data/genie-0.1/docs/classes/EntryProcessor.src/M000008.html +18 -0
  36. data/genie-0.1/docs/classes/EntryProcessor.src/M000009.html +20 -0
  37. data/genie-0.1/docs/classes/EntryProcessor.src/M000010.html +18 -0
  38. data/genie-0.1/docs/classes/EntryProcessor.src/M000011.html +23 -0
  39. data/genie-0.1/docs/classes/Log4r.html +114 -0
  40. data/genie-0.1/docs/classes/Log4r/LogEvent.html +153 -0
  41. data/genie-0.1/docs/classes/Log4r/LogEvent.src/M000123.html +16 -0
  42. data/genie-0.1/docs/classes/NotifiedProcessor.html +155 -0
  43. data/genie-0.1/docs/classes/NotifiedProcessor.src/M000094.html +22 -0
  44. data/genie-0.1/docs/classes/NullTransactionController.html +191 -0
  45. data/genie-0.1/docs/classes/NullTransactionController.src/M000030.html +16 -0
  46. data/genie-0.1/docs/classes/NullTransactionController.src/M000031.html +16 -0
  47. data/genie-0.1/docs/classes/Object.html +154 -0
  48. data/genie-0.1/docs/classes/Object.src/M000103.html +16 -0
  49. data/genie-0.1/docs/classes/Periodic.html +564 -0
  50. data/genie-0.1/docs/classes/Periodic.src/M000124.html +26 -0
  51. data/genie-0.1/docs/classes/Periodic.src/M000125.html +21 -0
  52. data/genie-0.1/docs/classes/Periodic.src/M000126.html +18 -0
  53. data/genie-0.1/docs/classes/Periodic.src/M000127.html +18 -0
  54. data/genie-0.1/docs/classes/Periodic.src/M000128.html +31 -0
  55. data/genie-0.1/docs/classes/Periodic.src/M000129.html +30 -0
  56. data/genie-0.1/docs/classes/Periodic.src/M000130.html +18 -0
  57. data/genie-0.1/docs/classes/Periodic.src/M000131.html +18 -0
  58. data/genie-0.1/docs/classes/Periodic.src/M000132.html +16 -0
  59. data/genie-0.1/docs/classes/PollingProcessor.html +303 -0
  60. data/genie-0.1/docs/classes/PollingProcessor.src/M000088.html +23 -0
  61. data/genie-0.1/docs/classes/PollingProcessor.src/M000089.html +19 -0
  62. data/genie-0.1/docs/classes/PollingProcessor.src/M000091.html +22 -0
  63. data/genie-0.1/docs/classes/PollingProcessor.src/M000092.html +18 -0
  64. data/genie-0.1/docs/classes/PollingProcessor.src/M000093.html +18 -0
  65. data/genie-0.1/docs/classes/Queue.html +562 -0
  66. data/genie-0.1/docs/classes/Queue.src/M000104.html +22 -0
  67. data/genie-0.1/docs/classes/Queue.src/M000105.html +18 -0
  68. data/genie-0.1/docs/classes/Queue.src/M000106.html +18 -0
  69. data/genie-0.1/docs/classes/Queue.src/M000107.html +18 -0
  70. data/genie-0.1/docs/classes/Queue.src/M000108.html +21 -0
  71. data/genie-0.1/docs/classes/Queue.src/M000109.html +21 -0
  72. data/genie-0.1/docs/classes/Queue.src/M000110.html +22 -0
  73. data/genie-0.1/docs/classes/Queue.src/M000111.html +16 -0
  74. data/genie-0.1/docs/classes/Queue.src/M000112.html +18 -0
  75. data/genie-0.1/docs/classes/Queue.src/M000113.html +19 -0
  76. data/genie-0.1/docs/classes/Queue.src/M000114.html +23 -0
  77. data/genie-0.1/docs/classes/Queue.src/M000115.html +21 -0
  78. data/genie-0.1/docs/classes/Queue.src/M000116.html +19 -0
  79. data/genie-0.1/docs/classes/Queue.src/M000117.html +20 -0
  80. data/genie-0.1/docs/classes/Queue.src/M000118.html +25 -0
  81. data/genie-0.1/docs/classes/Queue.src/M000119.html +18 -0
  82. data/genie-0.1/docs/classes/Queue.src/M000120.html +22 -0
  83. data/genie-0.1/docs/classes/Queue.src/M000121.html +22 -0
  84. data/genie-0.1/docs/classes/Queue.src/M000122.html +20 -0
  85. data/genie-0.1/docs/classes/QueueDispatcher.html +247 -0
  86. data/genie-0.1/docs/classes/QueueDispatcher.src/M000048.html +18 -0
  87. data/genie-0.1/docs/classes/QueueDispatcher.src/M000049.html +21 -0
  88. data/genie-0.1/docs/classes/QueueDispatcher.src/M000050.html +18 -0
  89. data/genie-0.1/docs/classes/QueueDispatcher.src/M000051.html +32 -0
  90. data/genie-0.1/docs/classes/QueueEntry.html +522 -0
  91. data/genie-0.1/docs/classes/QueueEntry.src/M000012.html +21 -0
  92. data/genie-0.1/docs/classes/QueueEntry.src/M000013.html +18 -0
  93. data/genie-0.1/docs/classes/QueueEntry.src/M000014.html +18 -0
  94. data/genie-0.1/docs/classes/QueueEntry.src/M000015.html +18 -0
  95. data/genie-0.1/docs/classes/QueueEntry.src/M000017.html +16 -0
  96. data/genie-0.1/docs/classes/QueueEntry.src/M000018.html +19 -0
  97. data/genie-0.1/docs/classes/QueueEntry.src/M000020.html +19 -0
  98. data/genie-0.1/docs/classes/QueueEntry.src/M000022.html +19 -0
  99. data/genie-0.1/docs/classes/QueueEntry.src/M000023.html +21 -0
  100. data/genie-0.1/docs/classes/QueueEntry.src/M000024.html +19 -0
  101. data/genie-0.1/docs/classes/QueueEntry.src/M000025.html +18 -0
  102. data/genie-0.1/docs/classes/QueueEntry.src/M000026.html +18 -0
  103. data/genie-0.1/docs/classes/QueueEntry.src/M000028.html +18 -0
  104. data/genie-0.1/docs/classes/Result.html +289 -0
  105. data/genie-0.1/docs/classes/Result.src/M000063.html +20 -0
  106. data/genie-0.1/docs/classes/Result.src/M000064.html +18 -0
  107. data/genie-0.1/docs/classes/Result.src/M000066.html +18 -0
  108. data/genie-0.1/docs/classes/Result.src/M000068.html +18 -0
  109. data/genie-0.1/docs/classes/Result.src/M000069.html +19 -0
  110. data/genie-0.1/docs/classes/SemanticCommand.html +229 -0
  111. data/genie-0.1/docs/classes/SemanticCommand.src/M000059.html +19 -0
  112. data/genie-0.1/docs/classes/SemanticCommand.src/M000060.html +18 -0
  113. data/genie-0.1/docs/classes/SemanticCommand.src/M000061.html +18 -0
  114. data/genie-0.1/docs/classes/TransactionBundle.html +260 -0
  115. data/genie-0.1/docs/classes/TransactionBundle.src/M000001.html +18 -0
  116. data/genie-0.1/docs/classes/TransactionBundle.src/M000002.html +20 -0
  117. data/genie-0.1/docs/classes/TransactionBundle.src/M000003.html +20 -0
  118. data/genie-0.1/docs/classes/TransactionBundle.src/M000004.html +18 -0
  119. data/genie-0.1/docs/classes/TransactionBundle.src/M000005.html +18 -0
  120. data/genie-0.1/docs/classes/TransactionBundle.src/M000007.html +19 -0
  121. data/genie-0.1/docs/classes/UndoRedoCommand.html +308 -0
  122. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000095.html +19 -0
  123. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000096.html +16 -0
  124. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000097.html +16 -0
  125. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000098.html +16 -0
  126. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000099.html +18 -0
  127. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000101.html +18 -0
  128. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000102.html +18 -0
  129. data/genie-0.1/docs/classes/UnitOfWork.html +322 -0
  130. data/genie-0.1/docs/classes/UnitOfWork.src/M000032.html +19 -0
  131. data/genie-0.1/docs/classes/UnitOfWork.src/M000033.html +18 -0
  132. data/genie-0.1/docs/classes/UnitOfWork.src/M000034.html +18 -0
  133. data/genie-0.1/docs/classes/UnitOfWork.src/M000035.html +18 -0
  134. data/genie-0.1/docs/classes/UnitOfWork.src/M000036.html +18 -0
  135. data/genie-0.1/docs/classes/UnitOfWork.src/M000037.html +18 -0
  136. data/genie-0.1/docs/classes/UnitOfWork.src/M000038.html +18 -0
  137. data/genie-0.1/docs/classes/UnitOfWork.src/M000039.html +18 -0
  138. data/genie-0.1/docs/classes/UnitOfWork.src/M000040.html +18 -0
  139. data/genie-0.1/docs/created.rid +1 -0
  140. data/genie-0.1/docs/dot/f_0.dot +14 -0
  141. data/genie-0.1/docs/dot/f_0.png +0 -0
  142. data/genie-0.1/docs/dot/f_1.dot +14 -0
  143. data/genie-0.1/docs/dot/f_1.png +0 -0
  144. data/genie-0.1/docs/dot/f_2.dot +14 -0
  145. data/genie-0.1/docs/dot/f_2.png +0 -0
  146. data/genie-0.1/docs/dot/f_3.dot +84 -0
  147. data/genie-0.1/docs/dot/f_3.png +0 -0
  148. data/genie-0.1/docs/dot/f_4.dot +14 -0
  149. data/genie-0.1/docs/dot/f_4.png +0 -0
  150. data/genie-0.1/docs/dot/f_5.dot +78 -0
  151. data/genie-0.1/docs/dot/f_5.png +0 -0
  152. data/genie-0.1/docs/dot/f_6.dot +50 -0
  153. data/genie-0.1/docs/dot/f_6.png +0 -0
  154. data/genie-0.1/docs/dot/f_7.dot +57 -0
  155. data/genie-0.1/docs/dot/f_7.png +0 -0
  156. data/genie-0.1/docs/dot/m_5_0.dot +30 -0
  157. data/genie-0.1/docs/dot/m_5_0.png +0 -0
  158. data/genie-0.1/docs/dot/m_7_0.dot +39 -0
  159. data/genie-0.1/docs/dot/m_7_0.png +0 -0
  160. data/genie-0.1/docs/files/License_txt.html +161 -0
  161. data/genie-0.1/docs/files/ReadMe_Amber_txt.html +491 -0
  162. data/genie-0.1/docs/files/ReadMe_txt.html +444 -0
  163. data/genie-0.1/docs/files/nist/genie/commands_rb.html +121 -0
  164. data/genie-0.1/docs/files/nist/genie/genie_rb.html +116 -0
  165. data/genie-0.1/docs/files/nist/genie/processors_rb.html +111 -0
  166. data/genie-0.1/docs/files/nist/genie/queues_rb.html +118 -0
  167. data/genie-0.1/docs/files/nist/genie/results_rb.html +117 -0
  168. data/genie-0.1/docs/fr_class_index.html +46 -0
  169. data/genie-0.1/docs/fr_file_index.html +34 -0
  170. data/genie-0.1/docs/fr_method_index.html +160 -0
  171. data/genie-0.1/docs/images/overview.jpg +0 -0
  172. data/genie-0.1/docs/index.html +24 -0
  173. data/genie-0.1/docs/rdoc-style.css +208 -0
  174. data/genie-0.1/lib/nist/genie/commands.rb +413 -0
  175. data/genie-0.1/lib/nist/genie/genie.rb +4 -0
  176. data/genie-0.1/lib/nist/genie/processors.rb +382 -0
  177. data/genie-0.1/lib/nist/genie/queues.rb +435 -0
  178. data/genie-0.1/lib/nist/genie/results.rb +113 -0
  179. data/genie-0.1/tests/helpers.rb +45 -0
  180. data/genie-0.1/tests/test_commands.rb +338 -0
  181. data/genie-0.1/tests/test_processors.rb +17 -0
  182. data/genie-0.1/tests/test_queues.rb +288 -0
  183. data/genie-0.1/tests/test_results.rb +37 -0
  184. data/trimurti-0.1.gem +0 -0
  185. data/trimurti-0.1/docs/classes/Array.html +176 -0
  186. data/trimurti-0.1/docs/classes/Array.src/M000005.html +19 -0
  187. data/trimurti-0.1/docs/classes/Array.src/M000006.html +19 -0
  188. data/trimurti-0.1/docs/classes/Asserter.html +136 -0
  189. data/trimurti-0.1/docs/classes/Brahma.html +360 -0
  190. data/trimurti-0.1/docs/classes/Brahma.src/M000029.html +21 -0
  191. data/trimurti-0.1/docs/classes/Brahma.src/M000030.html +20 -0
  192. data/trimurti-0.1/docs/classes/Brahma.src/M000031.html +36 -0
  193. data/trimurti-0.1/docs/classes/Brahma.src/M000032.html +18 -0
  194. data/trimurti-0.1/docs/classes/Brahma.src/M000033.html +20 -0
  195. data/trimurti-0.1/docs/classes/Brahma.src/M000034.html +21 -0
  196. data/trimurti-0.1/docs/classes/Brahma.src/M000035.html +25 -0
  197. data/trimurti-0.1/docs/classes/Brahma.src/M000036.html +22 -0
  198. data/trimurti-0.1/docs/classes/Brahma.src/M000037.html +22 -0
  199. data/trimurti-0.1/docs/classes/ComponentSpec.html +275 -0
  200. data/trimurti-0.1/docs/classes/ComponentSpec.src/M000001.html +21 -0
  201. data/trimurti-0.1/docs/classes/ComponentSpec.src/M000002.html +18 -0
  202. data/trimurti-0.1/docs/classes/DRb.html +165 -0
  203. data/trimurti-0.1/docs/classes/DRb.src/M000062.html +18 -0
  204. data/trimurti-0.1/docs/classes/DRb.src/M000063.html +18 -0
  205. data/trimurti-0.1/docs/classes/GUID.html +129 -0
  206. data/trimurti-0.1/docs/classes/Linda.html +444 -0
  207. data/trimurti-0.1/docs/classes/Linda.src/M000007.html +16 -0
  208. data/trimurti-0.1/docs/classes/Linda.src/M000008.html +16 -0
  209. data/trimurti-0.1/docs/classes/Linda.src/M000009.html +20 -0
  210. data/trimurti-0.1/docs/classes/Linda.src/M000010.html +16 -0
  211. data/trimurti-0.1/docs/classes/Linda.src/M000011.html +18 -0
  212. data/trimurti-0.1/docs/classes/Linda.src/M000012.html +21 -0
  213. data/trimurti-0.1/docs/classes/Linda.src/M000013.html +18 -0
  214. data/trimurti-0.1/docs/classes/Linda.src/M000014.html +18 -0
  215. data/trimurti-0.1/docs/classes/Linda.src/M000015.html +18 -0
  216. data/trimurti-0.1/docs/classes/Linda.src/M000016.html +18 -0
  217. data/trimurti-0.1/docs/classes/Linda.src/M000017.html +20 -0
  218. data/trimurti-0.1/docs/classes/Linda.src/M000018.html +20 -0
  219. data/trimurti-0.1/docs/classes/Object.html +153 -0
  220. data/trimurti-0.1/docs/classes/Object.src/M000021.html +18 -0
  221. data/trimurti-0.1/docs/classes/Plugins.html +174 -0
  222. data/trimurti-0.1/docs/classes/Plugins.src/M000024.html +32 -0
  223. data/trimurti-0.1/docs/classes/Plugins.src/M000025.html +32 -0
  224. data/trimurti-0.1/docs/classes/Plugins/Spec.html +267 -0
  225. data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000026.html +22 -0
  226. data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000027.html +18 -0
  227. data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000028.html +20 -0
  228. data/trimurti-0.1/docs/classes/QBE_ID.html +147 -0
  229. data/trimurti-0.1/docs/classes/QBE_ID.src/M000059.html +18 -0
  230. data/trimurti-0.1/docs/classes/QueryByExample.html +270 -0
  231. data/trimurti-0.1/docs/classes/QueryByExample.src/M000054.html +17 -0
  232. data/trimurti-0.1/docs/classes/QueryByExample.src/M000055.html +17 -0
  233. data/trimurti-0.1/docs/classes/QueryByExample.src/M000056.html +17 -0
  234. data/trimurti-0.1/docs/classes/QueryByExample.src/M000057.html +17 -0
  235. data/trimurti-0.1/docs/classes/QueryByExample.src/M000058.html +17 -0
  236. data/trimurti-0.1/docs/classes/Shiva.html +159 -0
  237. data/trimurti-0.1/docs/classes/Shiva.src/M000060.html +18 -0
  238. data/trimurti-0.1/docs/classes/Shiva.src/M000061.html +19 -0
  239. data/trimurti-0.1/docs/classes/String.html +176 -0
  240. data/trimurti-0.1/docs/classes/String.src/M000022.html +16 -0
  241. data/trimurti-0.1/docs/classes/String.src/M000023.html +16 -0
  242. data/trimurti-0.1/docs/classes/Symbol.html +176 -0
  243. data/trimurti-0.1/docs/classes/Symbol.src/M000003.html +16 -0
  244. data/trimurti-0.1/docs/classes/Symbol.src/M000004.html +16 -0
  245. data/trimurti-0.1/docs/classes/Trimurti.html +189 -0
  246. data/trimurti-0.1/docs/classes/Trimurti.src/M000019.html +16 -0
  247. data/trimurti-0.1/docs/classes/Trimurti.src/M000020.html +16 -0
  248. data/trimurti-0.1/docs/classes/Vishnu.html +563 -0
  249. data/trimurti-0.1/docs/classes/Vishnu.src/M000038.html +18 -0
  250. data/trimurti-0.1/docs/classes/Vishnu.src/M000039.html +18 -0
  251. data/trimurti-0.1/docs/classes/Vishnu.src/M000040.html +18 -0
  252. data/trimurti-0.1/docs/classes/Vishnu.src/M000041.html +22 -0
  253. data/trimurti-0.1/docs/classes/Vishnu.src/M000042.html +23 -0
  254. data/trimurti-0.1/docs/classes/Vishnu.src/M000043.html +24 -0
  255. data/trimurti-0.1/docs/classes/Vishnu.src/M000044.html +24 -0
  256. data/trimurti-0.1/docs/classes/Vishnu.src/M000045.html +18 -0
  257. data/trimurti-0.1/docs/classes/Vishnu.src/M000046.html +22 -0
  258. data/trimurti-0.1/docs/classes/Vishnu.src/M000047.html +20 -0
  259. data/trimurti-0.1/docs/classes/Vishnu.src/M000048.html +18 -0
  260. data/trimurti-0.1/docs/classes/Vishnu.src/M000049.html +22 -0
  261. data/trimurti-0.1/docs/classes/Vishnu.src/M000050.html +20 -0
  262. data/trimurti-0.1/docs/classes/Vishnu.src/M000051.html +19 -0
  263. data/trimurti-0.1/docs/classes/Vishnu.src/M000052.html +30 -0
  264. data/trimurti-0.1/docs/classes/Vishnu.src/M000053.html +21 -0
  265. data/trimurti-0.1/docs/created.rid +1 -0
  266. data/trimurti-0.1/docs/dot/f_0.dot +14 -0
  267. data/trimurti-0.1/docs/dot/f_0.png +0 -0
  268. data/trimurti-0.1/docs/dot/f_1.dot +14 -0
  269. data/trimurti-0.1/docs/dot/f_1.png +0 -0
  270. data/trimurti-0.1/docs/dot/f_2.dot +14 -0
  271. data/trimurti-0.1/docs/dot/f_2.png +0 -0
  272. data/trimurti-0.1/docs/dot/f_3.dot +39 -0
  273. data/trimurti-0.1/docs/dot/f_3.png +0 -0
  274. data/trimurti-0.1/docs/dot/f_4.dot +39 -0
  275. data/trimurti-0.1/docs/dot/f_4.png +0 -0
  276. data/trimurti-0.1/docs/dot/f_5.dot +69 -0
  277. data/trimurti-0.1/docs/dot/f_5.png +0 -0
  278. data/trimurti-0.1/docs/dot/f_6.dot +149 -0
  279. data/trimurti-0.1/docs/dot/f_6.png +0 -0
  280. data/trimurti-0.1/docs/dot/m_3_0.dot +30 -0
  281. data/trimurti-0.1/docs/dot/m_3_0.png +0 -0
  282. data/trimurti-0.1/docs/dot/m_4_0.dot +39 -0
  283. data/trimurti-0.1/docs/dot/m_4_0.png +0 -0
  284. data/trimurti-0.1/docs/dot/m_5_0.dot +40 -0
  285. data/trimurti-0.1/docs/dot/m_5_0.png +0 -0
  286. data/trimurti-0.1/docs/dot/m_5_1.dot +30 -0
  287. data/trimurti-0.1/docs/dot/m_5_1.png +0 -0
  288. data/trimurti-0.1/docs/dot/m_6_0.dot +40 -0
  289. data/trimurti-0.1/docs/dot/m_6_0.png +0 -0
  290. data/trimurti-0.1/docs/dot/m_6_1.dot +30 -0
  291. data/trimurti-0.1/docs/dot/m_6_1.png +0 -0
  292. data/trimurti-0.1/docs/dot/m_6_2.dot +30 -0
  293. data/trimurti-0.1/docs/dot/m_6_2.png +0 -0
  294. data/trimurti-0.1/docs/files/License_txt.html +132 -0
  295. data/trimurti-0.1/docs/files/ReadMe_Amber_txt.html +491 -0
  296. data/trimurti-0.1/docs/files/ReadMe_txt.html +694 -0
  297. data/trimurti-0.1/docs/files/nist/trimurti/linda_rb.html +129 -0
  298. data/trimurti-0.1/docs/files/nist/trimurti/plugins_rb.html +129 -0
  299. data/trimurti-0.1/docs/files/nist/trimurti/queryByExample_rb.html +128 -0
  300. data/trimurti-0.1/docs/files/nist/trimurti/trimurti_rb.html +151 -0
  301. data/trimurti-0.1/docs/fr_class_index.html +43 -0
  302. data/trimurti-0.1/docs/fr_file_index.html +33 -0
  303. data/trimurti-0.1/docs/fr_method_index.html +89 -0
  304. data/trimurti-0.1/docs/images/overview.jpg +0 -0
  305. data/trimurti-0.1/docs/index.html +24 -0
  306. data/trimurti-0.1/docs/rdoc-style.css +208 -0
  307. data/trimurti-0.1/lib/nist/trimurti/linda.rb +163 -0
  308. data/trimurti-0.1/lib/nist/trimurti/plugins.rb +107 -0
  309. data/trimurti-0.1/lib/nist/trimurti/queryByExample.rb +81 -0
  310. data/trimurti-0.1/lib/nist/trimurti/trimurti.rb +433 -0
  311. data/trimurti-0.1/tests/test_linda.rb +111 -0
  312. data/trimurti-0.1/tests/test_trimurti.rb +247 -0
  313. metadata +467 -0
@@ -0,0 +1,413 @@
1
+
2
+ require 'nist/common/guid'
3
+ require 'nist/common/log'
4
+ require 'nist/common/singletonReflection'
5
+
6
+ Object.outputters << Log4r::ObjectOutputter.new('CommandNotification')
7
+
8
+ # ==============================================
9
+
10
+ class Object
11
+
12
+ def resolve; self; end
13
+
14
+ end # Object
15
+
16
+ # ==============================================
17
+
18
+ # In addition to specifying some information about
19
+ # the commands associated with a particular semantic,
20
+ # instances contain Procs that tell the command how
21
+ # to 'do' and 'undo'. The default behavior is to
22
+ # send do_<semantics> or undo_<semantics> to the target.
23
+ class CommandMetainfo
24
+
25
+ @@registry = Hash.new
26
+
27
+ # Look up an instance.
28
+ def self.[](sym)
29
+ @@registry[sym]
30
+ end
31
+
32
+ # Look up an instance: identical to [].
33
+ def self.lookup(sym)
34
+ self[sym]
35
+ end
36
+
37
+ # The Symbol that identifies the command semantics.
38
+ attr_reader :semantics
39
+
40
+ # A string that a GUI can use to explain the command.
41
+ # Defaults to a String representation of the semantics.
42
+ attr_accessor :description
43
+
44
+ # An Integer (defaults to one).
45
+ attr_accessor :max_attempts
46
+
47
+ # A Boolean, true if the command might change
48
+ # data. If this is false, the command is
49
+ # guaranteed not to change any data: it is
50
+ # only a query.
51
+ attr_accessor :may_update
52
+
53
+ # A Boolean, true if the command has more complicated
54
+ # effects than a setter: defaults to true
55
+ attr_accessor :may_have_side_effects
56
+
57
+ # A Float that guesses how long the operation might
58
+ # take. It would be more accurate (but a nuisance)
59
+ # to maintain separate estimates for do and undo.
60
+ # The larger of the two is probably the best to use.
61
+ # For that matter, it would be nice to have separate
62
+ # estimates for CPU time and wall clock time.
63
+ # This value is not automatically maintaind: some
64
+ # separate process needs to periodically update
65
+ # this, based on the result's execution_seconds.
66
+ attr_accessor :estimated_seconds
67
+
68
+ # A Proc which takes arguments:
69
+ # 1. Target
70
+ # 2. Semantics
71
+ # 3. Argument Hash (should not be modified)
72
+ # 4. Undo data Hash (may have extra data added)
73
+ attr_accessor :do_proc
74
+
75
+ # An optional Proc which takes arguments:
76
+ # 1. Target
77
+ # 2. Semantics
78
+ # 3. Argument Hash (should not be modified. Includes undo data.)
79
+ # If the undo_proc is nil, the command can not be undone.
80
+ attr_accessor :undo_proc
81
+
82
+ # Sets the description as well as the semantics.
83
+ def semantics=(aSymbol)
84
+ @semantics=aSymbol
85
+ self.description=aSymbol.to_s
86
+ end
87
+
88
+ # New instances are automatically cached in the @@registry.
89
+ def initialize(semantics)
90
+ self.semantics=semantics
91
+ @@registry[semantics]=self
92
+ self.max_attempts=1
93
+ self.estimated_seconds=0.1
94
+ self.may_update=true
95
+ self.may_have_side_effects=true
96
+ self.do_proc=default_do_proc
97
+ self.undo_proc=default_undo_proc
98
+ end
99
+
100
+ # Returns the do_proc that gets used if you do not provide another.
101
+ def default_do_proc
102
+ lambda {|target, method_name, argHash, undoDataHash|
103
+ method_name = 'do_'+semantics.to_s
104
+ target.send(method_name, argHash, undoDataHash)
105
+ }
106
+ end
107
+
108
+ # Returns the undo_proc that gets used if you do not provide another.
109
+ def default_undo_proc
110
+ lambda {|target, semantics, argHash|
111
+ method_name = 'undo_'+semantics.to_s
112
+ target.send(method_name, argHash)
113
+ }
114
+ end
115
+
116
+ end # CommandMetainfo
117
+
118
+ # ==============================================
119
+
120
+ # An abstract factor. Has an invariant command_id,
121
+ # can wrap itself in a QueueEntry, and can
122
+ # make its inverse.
123
+ class BasicCommand
124
+
125
+ # Uniquely identifies this instance.
126
+ attr_reader :command_id
127
+
128
+ def initialize
129
+ @command_id=GUID.new
130
+ end
131
+
132
+ def to_entry
133
+ QueueEntry.new(self)
134
+ end
135
+
136
+ # Returns a command that undoes the receiver.
137
+ def inverse
138
+ UndoRedoCommand.new(self)
139
+ end
140
+
141
+ # Returns the chain of do/undo/redo actions
142
+ # culminating in the receiver. For most commands
143
+ # this returns an Array containing only the
144
+ # receiver. UndoRedoCommand instances return
145
+ # Arrays that have more than one element.
146
+ def command_chain
147
+ [self]
148
+ end
149
+
150
+ # Returns one of three Symbols (:do, :undo, :redo)
151
+ # depending on the function of the 'do' message.
152
+ # For most commands, this returns :do. Only
153
+ # UndoRedoCommands can return :undo or :redo.
154
+ def type; :do; end
155
+
156
+ end # BasicCommand
157
+
158
+ # ==============================================
159
+
160
+ # An abstract factor. Knows its semantics, and
161
+ # can use that knowlege to look up a CommandMetainfo
162
+ # (which answers several queries on behalf of the command).
163
+ class SemanticCommand < BasicCommand
164
+
165
+ # A Symbol that specifies what the command does
166
+ attr_accessor :semantics
167
+
168
+ def initialize(semantics)
169
+ self.semantics=semantics
170
+ super()
171
+ end
172
+
173
+ # Returns the CommandMetainfo that describes the receiver.
174
+ def metainfo
175
+ CommandMetainfo[semantics]
176
+ end
177
+
178
+ # Returns a Boolean, true if the command can be undone
179
+ # (because the metainfo posesses an undo_proc).
180
+ # Compare to QueueDispatcher#undo?
181
+ def undoable?
182
+ !metainfo.undo_proc.nil?
183
+ end
184
+ alias is_undoable undoable?
185
+
186
+ forward(:metainfo, CommandMetainfo, :max_attempts, :may_update, :may_have_side_effects, :estimated_seconds, :description)
187
+
188
+ end # SemanticCommand
189
+
190
+ # ==============================================
191
+
192
+ # Represents a basic operation. This implementation
193
+ # relies command description in the form of a CommandMetainfo
194
+ # that has semantics corresponding to the Command.
195
+ class Command < SemanticCommand
196
+
197
+ attr_accessor :target
198
+
199
+ attr_accessor :args
200
+
201
+ attr_accessor :undo_data
202
+
203
+ def initialize(semantics)
204
+ self.args=Hash.new
205
+ self.undo_data=Hash.new
206
+ super
207
+ end
208
+
209
+ def target_resolved
210
+ target.resolve
211
+ end
212
+
213
+ def args_resolved
214
+ answer = Hash.new
215
+ args.each {|key, value| answer[key]=value.resolve }
216
+ answer
217
+ end
218
+
219
+ # Returns a resolved Hash that includes
220
+ # undo_data as well as args.
221
+ def data_resolved
222
+ answer = args_resolved
223
+ undo_data.each {|key, value| answer[key]=value.resolve }
224
+ answer
225
+ end
226
+
227
+ # Builds a Result by executing a block with error handling and logging.
228
+ # FIXME: Logging needs to be per-thread, since several processors
229
+ # might be working in parallel.
230
+ def _execute(method)
231
+ answer = Result.new
232
+ notices = Log4r::Outputter['CommandNotification'].history
233
+ notices.clear
234
+ startTime = Time.now
235
+ begin
236
+ answer.result = yield
237
+ rescue LoggedFatal
238
+ # Do nothing, it's already logged
239
+ rescue Exception => e
240
+ # Log the exception (without throwing a new LoggedFatal)
241
+ cr = "\n\t"
242
+ self.logger.fatal("Command::#{method} caught exception of class #{e.class.name} with message <#{e.message}> and backtrace #{cr}<#{e.backtrace.join(cr)}>.")
243
+ end
244
+ answer.execution_seconds = Time.now - startTime
245
+ answer.add_notices(notices)
246
+ answer
247
+ end
248
+ private :_execute
249
+
250
+ def _do(cache_undo_data)
251
+ ud = cache_undo_data ? undo_data : Hash.new
252
+ answer = _execute('do') {metainfo.do_proc.call(target_resolved, semantics, args_resolved, ud)}
253
+ answer.undo_data=ud
254
+ answer
255
+ end
256
+ private :_do
257
+
258
+ def do()
259
+ _do(true)
260
+ end
261
+
262
+ def redo
263
+ _do(false)
264
+ end
265
+
266
+ def undo
267
+ if undoable?
268
+ return _execute('undo') {metainfo.undo_proc.call(target_resolved, semantics, data_resolved)}
269
+ end
270
+ answer = Result.new
271
+ answer.add_error("Attempt to undo a command (semantics=:#{semantics.to_s}) which is not undoable.")
272
+ answer
273
+ end
274
+
275
+
276
+ end # Command
277
+
278
+ # ==============================================
279
+
280
+ # Represents an indivisible collection of Commands
281
+ # that succeed or fail or as unit. Some metainformation
282
+ # (such as max_attempts) comes from the semantics-specified
283
+ # CommandMetainfo, but others (such as may_update and
284
+ # may_have_side_effects) are derived from the children.
285
+ # This is the safest thing to do. In principle one could
286
+ # implement a process which ensures that the CommandMetainfo
287
+ # is fully consistent with the chilren for all reasonable
288
+ # combinations of children, but that would probably be
289
+ # error prone.
290
+ class UnitOfWork < SemanticCommand
291
+
292
+ # An Array of component Commands.
293
+ attr_accessor :children
294
+
295
+ def initialize(semantics, *kids)
296
+ self.children=kids
297
+ super(semantics)
298
+ end
299
+
300
+ def size
301
+ children.size
302
+ end
303
+
304
+ def [](idx)
305
+ children[idx]
306
+ end
307
+
308
+ # which_method is either :do, :redo, or :undo
309
+ def _do(which_method)
310
+ answer = CompoundResult.new
311
+ children.each {|kid|
312
+ r = kid.send(which_method)
313
+ answer << r
314
+ break if r.error?
315
+ }
316
+ answer
317
+ end
318
+ private :_do
319
+
320
+ def do()
321
+ _do(:do)
322
+ end
323
+
324
+ def redo()
325
+ _do(:redo)
326
+ end
327
+
328
+ def undo()
329
+ _do(:undo)
330
+ end
331
+
332
+
333
+ def may_update
334
+ children.any? {|kid| kid.may_update }
335
+ end
336
+
337
+ def may_have_side_effects
338
+ children.any? {|kid| kid.may_have_side_effects }
339
+ end
340
+
341
+ # Returns a Boolean, true if the command can be undone
342
+ # (because the metainfo posesses an undo_proc).
343
+ # Compare to QueueDispatcher#undo?
344
+ def undoable?
345
+ children.all? {|kid| kid.undoable? }
346
+ end
347
+ alias is_undoable undoable?
348
+
349
+ end # UnitOfWork
350
+
351
+
352
+ # ==============================================
353
+
354
+ # Represents a command that undoes some other command.
355
+ # A redo is an undo of an undo.
356
+ class UndoRedoCommand < BasicCommand
357
+
358
+ # The command that gets undone (not the command at the end
359
+ # of the chain)
360
+ attr_accessor :command_undone
361
+
362
+ # The id of the command that gets undone. Used for marshalling.
363
+ attr_accessor :id_of_command_undone
364
+
365
+ def initialize(command)
366
+ self.command_undone=command
367
+ self.id_of_command_undone=command.command_id
368
+ end
369
+
370
+ forward(:command_undone, Command, :max_attempts, :may_update, :may_have_side_effects, :description)
371
+
372
+ def do(); command_undone.undo; end
373
+
374
+ def redo; self.do(); end
375
+
376
+ def undo; command_undone.redo; end
377
+
378
+ # Returns a Boolean, true if the command can be undone
379
+ # (because the metainfo posesses an undo_proc).
380
+ # Compare to QueueDispatcher#undo?
381
+ # This method always returns true, under the
382
+ # presumption that instance creation was valid.
383
+ # The first UndoRedoCommand in an undo/redo chain
384
+ # should be created only if the base command is
385
+ # undoable. Undoing the UndoRedoCommand is equivalent
386
+ # to a redo of the original command, so that is always
387
+ # possible.
388
+ def undoable?
389
+ true
390
+ end
391
+ alias is_undoable undoable?
392
+
393
+ # Returns the chain of do/undo/redo actions
394
+ # culminating in the receiver.
395
+ # UndoRedoCommand instances return
396
+ # Arrays that have more than one element.
397
+ # Other commands returns an Array containing
398
+ # only the receiver.
399
+ def command_chain
400
+ command_undone.command_chain << self
401
+ end
402
+
403
+ # Returns one of three Symbols (:do, :undo, :redo)
404
+ # depending on the function of the 'do' message.
405
+ # UndoRedoCommands can only return :undo or :redo.
406
+ # Other commands, only return :do.
407
+ def type
408
+ command_chain.size.even? ? :undo : :redo
409
+ end
410
+
411
+
412
+ end # UndoRedoCommand
413
+
@@ -0,0 +1,4 @@
1
+ require 'nist/genie/results'
2
+ require 'nist/genie/queues'
3
+ require 'nist/genie/commands'
4
+ require 'nist/genie/processors'
@@ -0,0 +1,382 @@
1
+
2
+
3
+ class EntryProcessor
4
+
5
+ # The queue whose entries are processed.
6
+ # Also the queue sending #entry_added.
7
+ attr_reader :queue
8
+
9
+ # Provides transactions
10
+ attr_accessor :transaction_controller
11
+
12
+ def initialize
13
+ self.transaction_controller = NullTransactionController.new
14
+ end
15
+
16
+ def queue=(aQueue)
17
+ queue.remove_watcher(self) if queue
18
+ @queue=aQueue
19
+ aQueue.add_watcher(self)
20
+ end
21
+
22
+ def _transact(err)
23
+ err ? transaction_controller.rollback : transaction_controller.commit
24
+ end
25
+
26
+ # Process the entry and commit its changes, if any.
27
+ def process(entry)
28
+ result = entry.do
29
+ commit_ok = true
30
+ err = result.error?
31
+ commit_ok = _transact(err) if entry.may_update
32
+ result.add_error('Commit failure') if !commit_ok
33
+ commit_ok && !err
34
+ end
35
+
36
+ end
37
+
38
+ # ========================================
39
+
40
+ # Processes each command as it is received.
41
+ class NotifiedProcessor < EntryProcessor
42
+
43
+ def entry_added(entry)
44
+ queue.claim_entry(entry)
45
+ process(entry)
46
+ process(entry) while entry.retry?
47
+ queue.processed(entry)
48
+ true
49
+ end
50
+
51
+ end # Processor
52
+
53
+ # ========================================
54
+
55
+ # A TransactionController that does nothing.
56
+ # For real transactions, see one of these (may need adaptors):
57
+ # * DBI http://ruby-dbi.sourceforge.net/
58
+ # * MySQL/Ruby http://www.tmtm.org/mysql/ruby/README.html
59
+ # * ODB http://brian.imxcc.com/odb/
60
+ # * Trans-simple http://raa.ruby-lang.org/project/trans-simple/
61
+ # * RDBC http://raa.ruby-lang.org/project/rdbc/
62
+ class NullTransactionController
63
+
64
+ def commit; true; end
65
+ def rollback; end
66
+
67
+ end # NullTransactionController
68
+
69
+ # ========================================
70
+
71
+ =begin rdoc
72
+ Mix this module into any class to give it the ability
73
+ to periodically kick of the do_behavior. Just send
74
+ it start and stop messages. These methods are asynchronous.
75
+ There are also synchronous versions that end in _synch.
76
+ Both versions take a Symbol that specifies the subtle
77
+ details of how the receiver should start or stop: see
78
+ VALID_START_SEMANTICS and VALID_STOP_SEMANTICS.
79
+
80
+ The do_behavior can be a Proc, Method, or Symbol.
81
+ It takes no arguments, should be thread safe, and
82
+ shuld be guaranteed not to raise an exception.
83
+ If your behavior might raise an exception, wrap
84
+ it in a Proc with exeption handling and logging.
85
+
86
+ This class offers some optional compensation for the time it
87
+ takes to execute do_behavior. Toward that end it
88
+ maintains a sequential list of the most recent
89
+ max_num_do_times measurements of the do_behavior.
90
+
91
+ This mixin is not currently thread safe: this feature
92
+ may be added later, but it does not look very necessary:
93
+ a single controller will probably manage all instances.
94
+
95
+ It was tempting to use a SimpleMachine to control the
96
+ internnal states. This does not buy us as much as it
97
+ would normally, perhaps because in this case most of
98
+ the events are internally generated.
99
+ def entry_state; :halted; end
100
+ def self.define_transitions
101
+ {
102
+ :halted => [:half_sleep, :sleep, :do],
103
+ :half_sleep => [:halted, :do],
104
+ :do => [:halted, :sleep],
105
+ :sleep => [:halted, :do]
106
+ }
107
+ end
108
+ def define_transitions; self.class.define_transitions; end
109
+ define_transit_tests(define_transitions)
110
+ write_missing_redispatch_templates(define_transitions)
111
+ =end
112
+ module Periodic
113
+
114
+ # Specifies the behavior that gets periodically
115
+ # executed. Either:
116
+ # * A Symbol executed by instance this is mixed into
117
+ # * A Proc
118
+ # * A Method
119
+ # Defaults to :process
120
+ attr_accessor :do_behavior
121
+
122
+ # A float representing either the sleep time,
123
+ # or the approximate time between invocations
124
+ # (depending on #subtract_do_time
125
+ attr_accessor :seconds
126
+
127
+ # A Boolean:
128
+ # * If true, attempt to adjust the sleep
129
+ # time so that #seconds includes the invocation time.
130
+ # * If false, #seconds represents the sleep time.
131
+ attr_accessor :subtract_do_time
132
+
133
+ # A Symbol that specifies the start semantics when
134
+ # #start is invoked without an argument,
135
+ attr_accessor :default_start_semantics
136
+
137
+ # A Symbol that specifies the stop semantics when
138
+ # #stop is invoked without an argument.
139
+ attr_accessor :default_stop_semantics
140
+
141
+ # An array of up to MAX_NUM_AVG Floats representing do times.
142
+ # All the times need to be kept, so that the do_times_total
143
+ # can be adjusted when a new measurement replaces an old one.
144
+ attr_accessor :do_times
145
+
146
+ # A float, the total of the values in do_times
147
+ attr_accessor :do_times_total
148
+
149
+ # An Integer that specifies the maximum number of
150
+ # measured execution times to keep track of when
151
+ # computing do_times_average
152
+ attr_reader :max_num_do_times
153
+
154
+ # Non nil while the instance is sleeping.
155
+ # We need to hold on to the thread so that
156
+ # it can be terminated if we need to stop
157
+ # immediately.
158
+ attr_reader :sleep_thread
159
+
160
+ # Non nil while the instance is performing
161
+ # the do_behavior.
162
+ # We need to hold on to the thread so that
163
+ # it can be terminated if we need to stop
164
+ # immediately.
165
+ attr_reader :do_thread
166
+
167
+ # A symbol that keeps track of the current state of the instance.
168
+ attr_reader :state
169
+
170
+ def initialize_periodic(seconds)
171
+ self.seconds=seconds
172
+ self.do_behavior=:process
173
+ self.subtract_do_time=true
174
+ self.default_start_semantics=:start_sleep
175
+ self.default_stop_semantics=:stop_during_sleep
176
+ self.do_times=Array.new
177
+ self.do_times_total=0.0
178
+ self.max_num_do_times=10
179
+ _halt!
180
+ end
181
+
182
+ # This setter has the following side effects if the new value is smaller than the old one:
183
+ # * do_times is truncated
184
+ # * do_times_total is changed
185
+ def max_num_do_times=(int)
186
+ @max_num_do_times=int
187
+ return unless int<do_times.size
188
+ do_times = do_times[do_times.size-int, int]
189
+ do_times_total = do_times.inject(0.0) {|sum, val| sum+val }
190
+ end
191
+
192
+ # An Array of Symbols describing the first thing that happens
193
+ # when you send #start.
194
+ # * :start_do - The do_behavior is invoked, followed by a sleep.
195
+ # * :start_sleep - The receiver sleeps before executing the do_behavior for the first time.
196
+ # * :start_half_sleep - The receiver sleeps half the normal time before executing the do_behavior.
197
+ VALID_START_SEMANTICS = [:start_do, :start_sleep, :start_half_sleep]
198
+
199
+ # An Array of Symbols describing how to stop.
200
+ # * :stop_immediately - abort the do_behavior (if running) as well as the sleep.
201
+ # * :stop_during_sleep - Let the do_behavior finish, if it is running.
202
+ # If the receiver is sleeping, stop immedately.
203
+ # * :stop_after_next_do - Let the current sleep and the subsequent do_behavior finish
204
+ # before stopping. If the do_behavior is already running, let it finish, but don't
205
+ # sleep or run the do_behavior again after that.
206
+ VALID_STOP_SEMANTICS = [:stop_immediately, :stop_after_next_do, :stop_during_sleep]
207
+
208
+ # An Array of Symbols describing valid state
209
+ VALID_STATES = [:halted, :running, :halt_scheduled, :halt_after_do_scheduled]
210
+
211
+ # Returns a Float, the time in seconds that the instance
212
+ # should sleep between invocations.
213
+ def sleep_time
214
+ subtract_do_time ? seconds - do_times_average : seconds
215
+ end
216
+
217
+ # A running average based on do_times_total
218
+ def do_times_average
219
+ do_times_total / do_times.size
220
+ end
221
+
222
+ # Start the reciever sychronousy according to start_semantics.
223
+ # Does not return until the instance has been stopped.
224
+ def start_synch(start_semantics=default_start_semantics)
225
+ fail "Invalid start_semantics: #{start_semantics.to_s}" unless VALID_START_SEMANTICS.include?(start_semantics)
226
+ _running!
227
+ case start_semantics
228
+ when :start_sleep
229
+ _sleep
230
+ when :start_half_sleep
231
+ _sleep(0.5)
232
+ end
233
+ while (_running? || _halt_after_do?)
234
+ _do
235
+ _halt! if halt_after_do?
236
+ _sleep if running
237
+ end
238
+ _halted!
239
+ end
240
+
241
+ # Start the reciever sychronousy according to stop_semantics.
242
+ # Does not return until the instance has been stopped.
243
+ def stop(stop_semantics=default_stop_semantics)
244
+ fail "Invalid stop_semantics: #{stop_semantics.to_s}" unless VALID_STOP_SEMANTICS.include?(stop_semantics)
245
+ case stop_semantics
246
+ when :stop_immediately
247
+ _halt!
248
+ _stop_thread(do_thread, stop_semantics)
249
+ _stop_thread(sleep_thread, stop_semantics)
250
+ when :stop_after_next_do
251
+ _halt_after_do!
252
+ # Don't stop any threads.
253
+ when :stop_during_sleep
254
+ _halt!
255
+ _stop_thread(sleep_thread, stop_semantics)
256
+ end
257
+ end
258
+
259
+ # Start the receiver according to start_semantics, and return immediately.
260
+ def start(start_semantics=default_start_semantics)
261
+ Thread.new{ start_synch(start_semantics) }
262
+ end
263
+
264
+ # Schedule the receiver to stop, in the mannner specified by stop_semantics.
265
+ # Returns immediately. Depending on stop_semantics, the receiver may
266
+ # execute one more time.
267
+ def stop_synch(stop_semantics=default_stop_semantics)
268
+ stop_synch(stop_semantics)
269
+ end
270
+
271
+ def running?; :running == state; end
272
+ alias _running? running?
273
+ alias is_running? running?
274
+
275
+ private
276
+
277
+ def _add_do_time(t)
278
+ do_times << t
279
+ do_times_total += t
280
+ do_times_total -= do_times.shift if do_times.size>max_num_do_times
281
+ end
282
+
283
+ def _do()
284
+ do_thread = Thread.current
285
+ startTime = Time.now
286
+ answer = case
287
+ when do_behavior.instance_of?(Symbol) : self.send(do_behavior)
288
+ when do_behavior.instance_of?(Proc) : do_behavior.call
289
+ when do_behavior.instance_of?(Method) : do_behavior.call
290
+ end
291
+ _add_do_time(Time.now-startTime)
292
+ do_thread = nil
293
+ rescue
294
+ ensure
295
+ answer
296
+ end
297
+
298
+ def _sleep(fraction=1)
299
+ sleep_thead = Thread.current
300
+ sleep(sleep_time * fraction)
301
+ sleep_thread = nil
302
+ rescue
303
+ ensure
304
+ end
305
+
306
+ def _stop_thread(thread, semantics)
307
+ thread.raise("Periodic mixin stopped with semantics #{semantics.to_s}") if thread
308
+ end
309
+
310
+ # Test state
311
+ def _halt_after_do?; :halt_after_do_scheduled == state; end
312
+ # Set state
313
+ def _running!; state = :running; end
314
+ def _halt!; state = :halt_scheduled; end
315
+ def _halted!; state = :halted; end
316
+ def _halt_after_do!; state = :halt_after_do_scheduled; end
317
+
318
+ end # Periodic
319
+
320
+ # ========================================
321
+
322
+ class PollingProcessor < EntryProcessor
323
+ include Periodic
324
+
325
+ # Prevents stale commands in the queue.
326
+ # The highest priority consideration in determining
327
+ # if the processor should process claims.
328
+ attr_accessor :max_command_age
329
+
330
+ # How much work the instance should request
331
+ # each time it processes commands.
332
+ # Insuficient work will result in a high transaction overhead.
333
+ attr_accessor :min_claim_time
334
+
335
+ # Large claim size increases odds of command conflict.
336
+ # An upper limit on how many commands will be
337
+ # processed at one time. Too many commands will increase
338
+ # the chance of a conflict. See also claim_size_limit
339
+ attr_accessor :max_claim_size
340
+
341
+ # Used to adjust the claim_size_limit. Normally 1.0.
342
+ # This is multiplied by the CLAIM_FRACTION_MULIPLIER
343
+ # each time a proccessing attempt fails. It is reset
344
+ # to 1.0 once a processing attempt succeeds.
345
+ attr_reader :claim_fraction
346
+
347
+ CLAIM_FRACTION_MULIPLIER=0.5
348
+
349
+ def initialize
350
+ initialize_periodic(1.0)
351
+ self.do_behavior=:action
352
+ self.max_max_periods_without_claims = 10
353
+ self.min_claim_size = 5
354
+ self.max_claim_size = 20
355
+ _reset
356
+ end
357
+
358
+ def claim?
359
+ queue.age_oldest_available > max_command_age &&
360
+ queue.estimated_seconds > min_claim_time
361
+ end
362
+ alias should_claim claim?
363
+
364
+ def action
365
+ return unless claim?
366
+ entry = queue.claim_seconds(min_claim_time, claim_size_limit)
367
+ success = process(entry)
368
+ queue.processed(entry)
369
+ success ? _reset : _shrink
370
+ end
371
+
372
+ # Shrink the claim_size_limit by muliplying claim_fraction by CLAIM_FRACTION_MULTIPLIER
373
+ def _shrink
374
+ @claim_fraction *= CLAIM_FRACTION_MULTIPLIER
375
+ end
376
+
377
+ # Reset the claim_size_limit by resetting claim_fraction to 1.0
378
+ def _reset
379
+ @claim_fraction = 1.0
380
+ end
381
+
382
+ end # PollingProcessor