1 /*
2  * MsgTrans - Message Transport Framework for DLang. Based on TCP, WebSocket, UDP transmission protocol.
3  *
4  * Copyright (C) 2019 HuntLabs
5  *
6  * Website: https://www.msgtrans.org
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module msgtrans.executor.Executor;
13 
14 import msgtrans.executor.ExecutorInfo;
15 
16 import hunt.logging.ConsoleLogger;
17 
18 import std.algorithm;
19 import std.format;
20 import std.range;
21 
22 /** 
23  * 
24  */
25 interface Executor {
26     // Grouped by the name
27     private __gshared ExecutorInfo[][string] _executors;
28 
29     static void registerExecutors(string name, ExecutorInfo[] executors...) {
30         
31         version(HUNT_DEBUG) {
32             foreach(ExecutorInfo e; executors) {
33                   tracef("Registing executor to %s, id: %d, method: %s in %s", name, e.messageId(), 
34                     e.methodInfo().getName(), e.classInfo().getFullName());  
35             }
36         }     
37 
38         auto itemPtr = name in _executors;
39         if(itemPtr is null) {
40             _executors[name] = executors.dup;
41         } else {
42             // collision check
43             ExecutorInfo[] existedexecutors = _executors[name];
44 
45             foreach(ExecutorInfo e; executors) {
46                 ExecutorInfo[] executorInfoes = existedexecutors.find!((ExecutorInfo a, uint b) 
47                     => a.messageId() == b)(e.messageId);
48 
49                 if(executorInfoes.length > 0) {
50                     ExecutorInfo executorInfo = executorInfoes[0];
51                     string msg = format("MessageId collision: id=%d in %s, between %s and %s",
52                         e.messageId, name, e.classInfo().getFullName(), executorInfo.classInfo().getFullName());
53                     warningf(msg);
54                     throw new Exception(msg);
55                 }    
56             }
57 
58             _executors[name] ~= executors.dup;
59         }
60     }
61 
62     static ExecutorInfo[] getExecutors(string name) {
63         auto itemPtr = name in _executors;
64         if(itemPtr is null)
65             return null;
66         return *itemPtr;
67     }
68 }