genie 0.1

Sign up to get free protection for your applications and to get access to all the features.
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