/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
- /**
- * AmbientTalk/2 Project
- * (c) Software Languages Lab, 2006 - 2011
- * Authors: Soft Ambient Group
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * @author eline.philips
- */
-
- def initModule := lobby.frameworks.workflow.WFinit;
- def environmentModule := lobby.frameworks.workflow.environment;
- def intensionalModule := lobby.frameworks.workflow.intensional;
- def crimeModule := lobby.bridges.crime.CrimeConnection;
- def standardPatternsModule := lobby.frameworks.workflow.standardPatterns;
- import crimeModule;
- import initModule;
- import environmentModule;
- import intensionalModule;
- import standardPatternsModule;
- import /.at.lang.values;
- import /.at.lang.futures;
- enableFutures(false);
- deftype Service;
- //TODO: ugly implementation, use something as volatile sets (experimental.lang)
- def ServiceDatabase := object: {
- def services := [];
- def servicesMapping := [];
-
- def findAll(tag) {
- def result := [];
- services.each: { |s| if: (is: s taggedAs: tag) then: {result := result + [s];}; };
- result;
- };
-
- def find(id) {
- def idx := servicesMapping.find: { |pair| pair[1] == id };
- def bla := if: (idx == nil) then: { "nil"; } else: { servicesMapping[idx][2]; }; //TODO
- if: (idx == nil) then: { nil; } else: { servicesMapping[idx][2]; };
- };
-
- def init() {
- whenever: Service discovered: { |service|
- if: (servicesMapping.map: { |pair| pair[2]; }).contains(service) then: {
- system.println("Service already discovered");
- } else: {
- system.println("service discovered ");
- when: service<-export(factId)@FutureMessage becomes: { |result|
- system.println("RESULT VAN EXPORT " + result);
- result.each: { |fact| myCrime.insertTuple(fact); };
- };
- //myCrime.insertTuple(makeTuple("FarRef", id, service));
- servicesMapping := servicesMapping + [[factId, service]];
- factId := factId + 1;
- services := services + [service];
- whenever: service disconnected: {
- system.println("Service disconnected");
- // TODO myCrime retract
- def idx := services.find: { |s| s == service; };
- services := services.select(1, idx) + services.select(idx + 1, services.length());
- };
- };
- };
- };
- };
- def SnapshotGroup(d, var, cmp, syncBarrier := SynchronizingBarrier(percentage(100))) {
- object: {
- def description := d;
- def varName := var;
- def component := Sequence(cmp, syncBarrier);
- def started := false;
- def numberOfParticipants := 0;
-
- def start(env) {
- env.insert(`groupInfo, self);
- def [result, resolver] := makeFuture();
- execute(env, resolver);
- result;
- };
-
- def execute(env, resolver) {
- def ServiceDB := env.find(`serviceDB);
- def services := [];
- if: (is: description taggedAs: Rule) then: {
- description.findall( { |varMaps| varMaps.each: { |v|
- def s := ServiceDB.find(v.get(`id));
- services := services + [s]; };
- numberOfParticipants := services.length();
- executeServices(env, resolver, services) ;});
- } else: {
- services := ServiceDB.findAll(groupTag);
- executeServices(env, resolver, services);
- };
- };
-
- def executeServices(env, resolver, services) {
- groupId := groupId + 1;
- def envs := [];
- services.each: { |s| def clonedEnv := Environment.new(env);
- clonedEnv.insert(varName, s);
- when: component.start(clonedEnv) becomes: { |nEnv|
- nEnv.delete(`groupInfo);
- nEnv.delete(varName);
- resolver.resolve(nEnv); };
- };
- };
- } taggedAs: [Pattern];
- };
- def Barrier(c) {
- object: {
- def condition := c;
- def resultEnvs := [];
- def futures := [];
- def check := false;
-
- def start(env) {
- def [result, resolver] := makeFuture();
- resultEnvs := resultEnvs + [env];
- execute(env, resolver);
- result;
- };
- def execute(env, resolver) {
- def group := env.find(`groupInfo);
- if: check then: {
- system.println("barrier checked");
- resolver.resolve(env);
- } else: {
- if: condition(self, group) then: {
- system.println("barrier passed");
- check := true;
- futures := futures + [resolver];
- def idx := 0;
- futures.each: { |r| idx := idx+1; r.resolve(resultEnvs[idx]); };
- } else: {
- system.println("barrier not yet ok");
- futures := futures + [resolver];
- };
- };
- };
- } taggedAs: [Pattern];
- };
- def SynchronizingBarrier(c) {
- object: {
- def condition := c;
- def resultEnvs := [];
- def futures := [];
- def check := false;
- def first := true;
- def [result, resolver];
-
- def start(env) {
- resultEnvs := resultEnvs + [env];
- if: first then: {
- first := false;
- [result, resolver] := makeFuture();
- };
- execute(env);
- result;
- };
- def execute(env) {
- def group := env.find(`groupInfo);
- if: check then: {
- system.println("barrier already passed");
- } else: {
- if: condition(self, group) then: {
- system.println("barrier passed");
- check := true;
- futures := futures + [resolver];
- def newEnv := resultEnvs[1];
- newEnv.merge(resultEnvs.select(2, resultEnvs.length()+1), true);
- resolver.resolve(newEnv);
- } else: {
- system.println("barrier not yet ok");
- futures := futures + [resolver];
- };
- };
- };
- } taggedAs: [Pattern];
- };
- def amount(n) {
- { |barrier, group| barrier.resultEnvs.length() >= n; };
- };
- def positive(varName, varValue, n) {
- { |barrier, group|
- def envs := barrier.resultEnvs.filter( { |e| e.find(varName) == varValue; });
- envs.length() >= n;
- };
- };
- def percentage(n) {
- { |barrier, group|
- def nbr := group.numberOfParticipants;
- def envs := barrier.resultEnvs;
- nbr / envs >= n /100;
- };
- };
- def CRIMEGroupInteractionsModule := object: {
- deftype Service;
- def ServiceDatabase := ServiceDatabase;
- def SnapshotGroup := &SnapshotGroup;
- def Barrier := &Barrier;
- def SynchronizingBarrier := &SynchronizingBarrier;
- def amount := &amount;
- def positive := &positive;
- def percentage := &percentage;
- };