Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

398
LINES

< > BotCompany Repo | #1002317 // Sub-Bot Dispatcher (LIVE)

JavaX source code [tags: dont-transpile use-pretranspiled] - run with: x30.jar

Libraryless. Click here for Pure Java version (8044L/52K).

1  
!7
2  
3  
set flag Matches_fsi.
4  
5  
static new L<Bot> bots;
6  
static S whoSaidThat;
7  
static new ThreadLocal<S> sendingAnswer;
8  
static new ThreadLocal<Bool> dispatcherAuth;
9  
static ThreadLocal<L<Answer>> answers = new ThreadLocal;
10  
static boolean showMultiResponse = false;
11  
static Set<S> reloading = syncSet();
12  
13  
static class Answer {
14  
  S bot, text;
15  
  
16  
  *(S *bot, S *text) {}
17  
  *() {}
18  
}
19  
20  
static volatile S loadingBotID;
21  
22  
static class Bot {
23  
  S id; // always formatted
24  
  boolean enabled, always;
25  
  double prio;
26  
  
27  
  *(S *id, boolean *enabled) {}
28  
  *() {}
29  
}
30  
31  
static Map<S, Class> classes = synchroTreeMap();
32  
33  
// wait while a bot is reloading; not used yet
34  
static Set<S> gracePeriods = expiringSet(20.0);
35  
36  
static volatile long ticks;
37  
static volatile boolean tickActionsEnabled = true;
38  
39  
p {
40  
  load("bots");
41  
  loadAll();
42  
  
43  
  load("ticks");
44  
  load("tickActionsEnabled");
45  
  //startTicking();
46  
}
47  
48  
static void loadAll() {
49  
  for (Bot bot : bots) pcall {
50  
    loadBot(bot);
51  
  }
52  
}
53  
54  
static void loadBot(Bot bot) {
55  
  loadingBotID = bot.id;
56  
  try {
57  
    Class c;
58  
    try {
59  
      c = hotwire(bot.id);
60  
    } catch (Throwable e) {
61  
      throw new RuntimeException("Error in hotwire of " + bot.id, e);
62  
    }
63  
    classes.put(bot.id, c);
64  
    setOpt(c, "mainBot", getMainBot());
65  
    try {
66  
      callMain(c);
67  
    } catch (Throwable e) {
68  
      throw new RuntimeException("Error in main of " + bot.id, e);
69  
    }
70  
  } finally {
71  
    loadingBotID = null;
72  
  }
73  
}
74  
75  
static Class getSubBot(S id) {
76  
  ret getBot(id);
77  
}
78  
79  
static Class getBot(S id) {
80  
  ret classes.get(formatSnippetID(id));
81  
}
82  
83  
static Bot findSubBot(S id) {
84  
  ret findByField(bots, "id", formatSnippetID(id));
85  
}
86  
87  
answer {
88  
try {
89  
 synchronized(main.class) {
90  
  if "ticks" ret str(ticks);
91  
  
92  
  if (master()) {
93  
    if "enable ticks" {
94  
      tickActionsEnabled = true;
95  
      save("tickActionsEnabled");
96  
      ret "OK, enabled";
97  
    }
98  
    
99  
    if "disable ticks" {
100  
      tickActionsEnabled = false;
101  
      save("tickActionsEnabled");
102  
      ret "OK, disabled";
103  
    }
104  
  }
105  
  
106  
  if "count sub bots"
107  
    ret lstr(getSubBots());
108  
109  
  if "full list sub bots"
110  
    ret slackSnippet(structureLines(getSubBots()));
111  
112  
  if "list sub bots" {
113  
    new L<S> notLoaded;
114  
    L<Bot> bots = getSubBots();
115  
    for (Bot bot : bots)
116  
      if (!classes.containsKey(bot.id))
117  
        notLoaded.add(bot.id);
118  
    S a = "Enabled: " + structure(collectField(filterByField(bots, "enabled", true), "id")) + ". Disabled: " + structure(collectField(filterByField(bots, "enabled", false), "id"));
119  
    if (!empty(notLoaded))
120  
      a += ". Not loaded: " + structure(notLoaded);
121  
    ret a;
122  
  }
123  
  
124  
  if "bot prios" {
125  
    new MultiMap<Double, S> map;
126  
    for (Bot bot : bots)
127  
      map.put(bot.prio, bot.id);
128  
    map.remove(0.0);
129  
    ret slackSnippet("Listing all but prio 0:\n"+ structureLines(map.data));
130  
  }
131  
    
132  
  if "is * a sub bot?"
133  
    ret findSubBot(m.unq(0)) != null ? "yes": "no";
134  
    
135  
  if (master()) {
136  
  
137  
    if "add sub bots *" {
138  
      L<S> bots = (L) safeUnstructure(m.unq(0));
139  
      new L<S> out;
140  
      for (S id : bots) pcall {
141  
        S q = format("add sub bot *", id);
142  
        out.add(q + " => ");
143  
        appendToLast(out, askSelf(q));
144  
      }
145  
      ret slackSnippet(fromLines(out));
146  
    }
147  
    if "add sub bot *" {
148  
      S id = m.fsi(0);
149  
      Bot bot = findSubBot(id);
150  
      if (bot != null) {
151  
        bots.remove(bot);
152  
        bots.add(0, bot);
153  
        save("bots");
154  
        ret "OK, bumped.";
155  
      }
156  
      bots.add(0, bot = new Bot(id, true));
157  
      save("bots");
158  
      loadBot(bot);
159  
      ret format("OK, * loaded & added to top.", id);
160  
    }
161  
    
162  
    if "enable sub bot *" {
163  
      S id = m.fsi(0);
164  
      Bot bot = findSubBot(id);
165  
      if (bot != null) {
166  
        bot.enabled = true;
167  
        save("bots");
168  
        ret "OK, enabled.";
169  
      }
170  
      ret "woot";
171  
    }
172  
    
173  
    if "disable sub bot *" {
174  
      S id = m.fsi(0);
175  
      Bot bot = findSubBot(id);
176  
      if (bot != null) {
177  
        bot.enabled = false;
178  
        save("bots");
179  
        ret "OK, disabled.";
180  
      }
181  
      ret "woot";
182  
    }
183  
    
184  
    // an "always bot" is one that should read all msgs
185  
    
186  
    if "enable always bot *" {
187  
      S id = m.fsi(0);
188  
      Bot bot = findSubBot(id);
189  
      if (bot != null) {
190  
        bot.always = true;
191  
        save("bots");
192  
        ret "OK, has status 'always' now.";
193  
      }
194  
      ret "woot";
195  
    }
196  
    
197  
    if "disable always bot *" {
198  
      S id = m.fsi(0);
199  
      Bot bot = findSubBot(id);
200  
      if (bot != null) {
201  
        bot.always = false;
202  
        save("bots");
203  
        ret "OK, lost status 'always'.";
204  
      }
205  
      ret "woot";
206  
    }
207  
    
208  
    if "prio bot * *" {
209  
      S id = m.fsi(0);
210  
      double newPrio = parseDouble(m.unq(1));
211  
      Bot bot = findSubBot(id);
212  
      if (bot != null) {
213  
        bot.prio = newPrio;
214  
        save("bots");
215  
        ret format("OK, prio changed to *", newPrio);
216  
      }
217  
      ret "woot";
218  
    }
219  
    
220  
    if "list bot *"
221  
      ret structure(findSubBot(m.unq(0)));
222  
223  
    if "remove sub bot *" {
224  
      S id = m.fsi(0);
225  
      Bot bot = findSubBot(id);
226  
      if (bot != null) {
227  
        bots.remove(bot);
228  
        save("bots");
229  
        
230  
        cleanUp(classes.get(id));
231  
        classes.remove(id);
232  
        ret "OK, removed.";
233  
      }
234  
      ret "woot not there anyway";
235  
    }
236  
    
237  
    if (match("reload sub bot *", s, m) || match("reload sub *", s, m)) {
238  
      S id = m.fsi(0);
239  
      long time = sysNow();
240  
      Bot bot = findSubBot(id);
241  
      if (bot != null) {
242  
        gracePeriods.add(id);
243  
        temp tempAdd(reloading, id);
244  
        cleanUp(classes.get(id));
245  
        classes.remove(id);
246  
        loadBot(bot);
247  
        ret "OK, reloaded in " + renderElapsedTimePleasantly_100ms(elapsedMS(time));
248  
      }
249  
      ret "woot not found";
250  
    }
251  
  }
252  
  
253  
  
254  
 }
255  
 
256  
  // dispatch to sub bots
257  
  
258  
  O randomChecker = getBot("#1003005");
259  
260  
  L<Bot> dehbots = getSubBots();
261  
262  
  sendingAnswer.set(null);
263  
  answers.set(new L);
264  
  boolean showMultiResponse = main.showMultiResponse || tb();
265  
  for (Bot bot : dehbots) pcall {
266  
    if (!bot.enabled) continue;
267  
    Class c = classes.get(bot.id);
268  
    if (c != null) {
269  
      //print("Dispatching to " + bot.id);
270  
      S a = callStaticAnswerMethod(c, s);
271  
      if (!empty(a)) {
272  
        sendingAnswer.set(a);
273  
        answers.get().add(new Answer(bot.id, a));
274  
        whoSaidThat = bot.id;
275  
        if (!showMultiResponse) {
276  
          informAlwaysBots(subList(dehbots, dehbots.indexOf(bot)+1), s);
277  
          ret sendingAnswer.get();
278  
        }
279  
      }
280  
    }
281  
  }
282  
  
283  
  if (showMultiResponse) {
284  
    new L<Answer> nonrand;
285  
    new L<Answer> rand;
286  
    for (Answer a : answers.get())
287  
      (isRandomBot(randomChecker, a.bot) ? rand : nonrand).add(a);
288  
      
289  
    // only show random if there is no non-random response
290  
    if (empty(nonrand)) nonrand.addAll(rand);
291  
    
292  
    L<Answer> l = nonrand;
293  
    new L<S> list;
294  
    if (empty(l)) ret null;
295  
    if (l(l) == 1) ret first(l).text;
296  
    for (Answer a : l)
297  
      setAdd(list, "[" + a.bot + "] " + a.text);
298  
    ret fromLines(list);
299  
  }
300  
} catch (Throwable e) { printStackTrace(e); ret str(e); }
301  
}
302  
303  
static synchronized void cleanMeUp() {
304  
  print("Cleaning up " + l(classes) + " sub-bots");
305  
  for (Class c : classes.values())
306  
    cleanUp(c);
307  
  classes.clear();
308  
  save("ticks");
309  
}
310  
311  
static void informAlwaysBots(L<Bot> bots, S s) {
312  
  for (Bot bot : bots)
313  
    if (bot.always) pcall {
314  
      Class c = classes.get(bot.id);
315  
      if (c != null) {
316  
        S a = callStaticAnswerMethod(c, s);
317  
        if (!empty(a))
318  
          print("Always bot " + bot.id + " said quietly: " + quote(a));
319  
      }
320  
    }
321  
}
322  
323  
static synchronized L<S> getSubBotIDs() {
324  
  ret collectField(getSubBots(), "id");
325  
}
326  
327  
static synchronized L<Bot> getSubBots() {
328  
  ret reversedList(sortedByField(bots, "prio"));
329  
  /*ret concatLists(
330  
    filterByField(bots, "lowPrio", false),
331  
    filterByField(bots, "lowPrio", true));*/
332  
}
333  
334  
static Class getClassOfSubBot(S id) {
335  
  ret classes.get(id);
336  
}
337  
338  
// loaded / total
339  
static int[] numLoaded() {
340  
  ret new int[] {l(classes), l(bots) };
341  
}
342  
343  
static void addSeedBot(S id) {
344  
  Bot bot = findSubBot(id);
345  
  if (bot != null) {
346  
    printF("Seed bot * already there.", id);
347  
    ret;
348  
  }
349  
  bots.add(0, bot = new Bot(id, true));
350  
  save("bots");
351  
  loadBot(bot);
352  
  printF("OK, seed bot * loaded & added to top.", id);
353  
}
354  
355  
static void startTicking() {
356  
  thread "Ticker" {
357  
    while true {
358  
      if (tickActionsEnabled) pcall {
359  
        tick();
360  
      }
361  
      ++ticks;
362  
      sleep(250);
363  
    }
364  
  }
365  
}
366  
367  
static void tick() {
368  
  L<Bot> dehbots = getSubBots();
369  
370  
  for (Bot bot : dehbots) pcall {
371  
    if (!bot.enabled) continue;
372  
    Class c = classes.get(bot.id);
373  
    if (c != null)
374  
      callOpt(c, "tick");
375  
  }
376  
}
377  
378  
static S getSendingAnswer() {
379  
  ret sendingAnswer.get();
380  
}
381  
382  
static void overwriteAnswer(S a) {
383  
  sendingAnswer.set(a);
384  
}
385  
386  
static boolean isRandomBot(O randomChecker, S id) {
387  
  if (randomChecker == null) ret false;
388  
  pcall {
389  
    ret (bool) call(randomChecker, "isRandomBot", id);
390  
  }
391  
  ret false;
392  
}
393  
394  
sbool master() { ret webAuthed() || isTrue(dispatcherAuth!); }
395  
396  
sbool isReloading(S botID) {
397  
  ret contains(reloading, fsIOpt(botID));
398  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1002317
Snippet name: Sub-Bot Dispatcher (LIVE)
Eternal ID of this version: #1002317/11
Text MD5: 1a71ed3d3aee53c43e8567595393d558
Transpilation MD5: 219ac1c415febc55983caf144d5b276e
Author: stefan
Category: eleu
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-05-21 17:50:29
Source code size: 9379 bytes / 398 lines
Pitched / IR pitched: No / No
Views / Downloads: 1060 / 8481
Version history: 10 change(s)
Referenced in: [show references]