/atlib/branches/reflective/frameworks/workflow/CRIMEgroupInteractions.at

http://ambienttalk.googlecode.com/ · Unknown · 248 lines · 215 code · 33 blank · 0 comment · 0 complexity · eab64c5797dfb1fa9fb432caaa16a4df MD5 · raw file

  1. /**
  2. * AmbientTalk/2 Project
  3. * (c) Software Languages Lab, 2006 - 2011
  4. * Authors: Soft Ambient Group
  5. *
  6. * Permission is hereby granted, free of charge, to any person
  7. * obtaining a copy of this software and associated documentation
  8. * files (the "Software"), to deal in the Software without
  9. * restriction, including without limitation the rights to use,
  10. * copy, modify, merge, publish, distribute, sublicense, and/or
  11. * sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following
  13. * conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be
  16. * included in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  20. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  22. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  23. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  24. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25. * OTHER DEALINGS IN THE SOFTWARE.
  26. *
  27. * @author eline.philips
  28. */
  29. def initModule := lobby.frameworks.workflow.WFinit;
  30. def environmentModule := lobby.frameworks.workflow.environment;
  31. def intensionalModule := lobby.frameworks.workflow.intensional;
  32. def crimeModule := lobby.bridges.crime.CrimeConnection;
  33. def standardPatternsModule := lobby.frameworks.workflow.standardPatterns;
  34. import crimeModule;
  35. import initModule;
  36. import environmentModule;
  37. import intensionalModule;
  38. import standardPatternsModule;
  39. import /.at.lang.values;
  40. import /.at.lang.futures;
  41. enableFutures(false);
  42. deftype Service;
  43. //TODO: ugly implementation, use something as volatile sets (experimental.lang)
  44. def ServiceDatabase := object: {
  45. def services := [];
  46. def servicesMapping := [];
  47. def findAll(tag) {
  48. def result := [];
  49. services.each: { |s| if: (is: s taggedAs: tag) then: {result := result + [s];}; };
  50. result;
  51. };
  52. def find(id) {
  53. def idx := servicesMapping.find: { |pair| pair[1] == id };
  54. def bla := if: (idx == nil) then: { "nil"; } else: { servicesMapping[idx][2]; }; //TODO
  55. if: (idx == nil) then: { nil; } else: { servicesMapping[idx][2]; };
  56. };
  57. def init() {
  58. whenever: Service discovered: { |service|
  59. if: (servicesMapping.map: { |pair| pair[2]; }).contains(service) then: {
  60. system.println("Service already discovered");
  61. } else: {
  62. system.println("service discovered ");
  63. when: service<-export(factId)@FutureMessage becomes: { |result|
  64. system.println("RESULT VAN EXPORT " + result);
  65. result.each: { |fact| myCrime.insertTuple(fact); };
  66. };
  67. //myCrime.insertTuple(makeTuple("FarRef", id, service));
  68. servicesMapping := servicesMapping + [[factId, service]];
  69. factId := factId + 1;
  70. services := services + [service];
  71. whenever: service disconnected: {
  72. system.println("Service disconnected");
  73. // TODO myCrime retract
  74. def idx := services.find: { |s| s == service; };
  75. services := services.select(1, idx) + services.select(idx + 1, services.length());
  76. };
  77. };
  78. };
  79. };
  80. };
  81. def SnapshotGroup(d, var, cmp, syncBarrier := SynchronizingBarrier(percentage(100))) {
  82. object: {
  83. def description := d;
  84. def varName := var;
  85. def component := Sequence(cmp, syncBarrier);
  86. def started := false;
  87. def numberOfParticipants := 0;
  88. def start(env) {
  89. env.insert(`groupInfo, self);
  90. def [result, resolver] := makeFuture();
  91. execute(env, resolver);
  92. result;
  93. };
  94. def execute(env, resolver) {
  95. def ServiceDB := env.find(`serviceDB);
  96. def services := [];
  97. if: (is: description taggedAs: Rule) then: {
  98. description.findall( { |varMaps| varMaps.each: { |v|
  99. def s := ServiceDB.find(v.get(`id));
  100. services := services + [s]; };
  101. numberOfParticipants := services.length();
  102. executeServices(env, resolver, services) ;});
  103. } else: {
  104. services := ServiceDB.findAll(groupTag);
  105. executeServices(env, resolver, services);
  106. };
  107. };
  108. def executeServices(env, resolver, services) {
  109. groupId := groupId + 1;
  110. def envs := [];
  111. services.each: { |s| def clonedEnv := Environment.new(env);
  112. clonedEnv.insert(varName, s);
  113. when: component.start(clonedEnv) becomes: { |nEnv|
  114. nEnv.delete(`groupInfo);
  115. nEnv.delete(varName);
  116. resolver.resolve(nEnv); };
  117. };
  118. };
  119. } taggedAs: [Pattern];
  120. };
  121. def Barrier(c) {
  122. object: {
  123. def condition := c;
  124. def resultEnvs := [];
  125. def futures := [];
  126. def check := false;
  127. def start(env) {
  128. def [result, resolver] := makeFuture();
  129. resultEnvs := resultEnvs + [env];
  130. execute(env, resolver);
  131. result;
  132. };
  133. def execute(env, resolver) {
  134. def group := env.find(`groupInfo);
  135. if: check then: {
  136. system.println("barrier checked");
  137. resolver.resolve(env);
  138. } else: {
  139. if: condition(self, group) then: {
  140. system.println("barrier passed");
  141. check := true;
  142. futures := futures + [resolver];
  143. def idx := 0;
  144. futures.each: { |r| idx := idx+1; r.resolve(resultEnvs[idx]); };
  145. } else: {
  146. system.println("barrier not yet ok");
  147. futures := futures + [resolver];
  148. };
  149. };
  150. };
  151. } taggedAs: [Pattern];
  152. };
  153. def SynchronizingBarrier(c) {
  154. object: {
  155. def condition := c;
  156. def resultEnvs := [];
  157. def futures := [];
  158. def check := false;
  159. def first := true;
  160. def [result, resolver];
  161. def start(env) {
  162. resultEnvs := resultEnvs + [env];
  163. if: first then: {
  164. first := false;
  165. [result, resolver] := makeFuture();
  166. };
  167. execute(env);
  168. result;
  169. };
  170. def execute(env) {
  171. def group := env.find(`groupInfo);
  172. if: check then: {
  173. system.println("barrier already passed");
  174. } else: {
  175. if: condition(self, group) then: {
  176. system.println("barrier passed");
  177. check := true;
  178. futures := futures + [resolver];
  179. def newEnv := resultEnvs[1];
  180. newEnv.merge(resultEnvs.select(2, resultEnvs.length()+1), true);
  181. resolver.resolve(newEnv);
  182. } else: {
  183. system.println("barrier not yet ok");
  184. futures := futures + [resolver];
  185. };
  186. };
  187. };
  188. } taggedAs: [Pattern];
  189. };
  190. def amount(n) {
  191. { |barrier, group| barrier.resultEnvs.length() >= n; };
  192. };
  193. def positive(varName, varValue, n) {
  194. { |barrier, group|
  195. def envs := barrier.resultEnvs.filter( { |e| e.find(varName) == varValue; });
  196. envs.length() >= n;
  197. };
  198. };
  199. def percentage(n) {
  200. { |barrier, group|
  201. def nbr := group.numberOfParticipants;
  202. def envs := barrier.resultEnvs;
  203. nbr / envs >= n /100;
  204. };
  205. };
  206. def CRIMEGroupInteractionsModule := object: {
  207. deftype Service;
  208. def ServiceDatabase := ServiceDatabase;
  209. def SnapshotGroup := &SnapshotGroup;
  210. def Barrier := &Barrier;
  211. def SynchronizingBarrier := &SynchronizingBarrier;
  212. def amount := &amount;
  213. def positive := &positive;
  214. def percentage := &percentage;
  215. };