1 module libsweatyballs.router.core;
2 
3 import libsweatyballs.link.core : Link;
4 import libsweatyballs.security.identity : Identity;
5 import libsweatyballs.router.table : Table, Route;
6 import core.thread : Thread, dur;
7 import core.sync.mutex : Mutex;
8 import libsweatyballs.router.advertiser : Advertiser;
9 import libsweatyballs.engine.core : Engine;
10 import gogga;
11 import std.conv : to;
12 import std.datetime : Clock;
13 
14 /**
15 * Router
16 *
17 * Description: TODO
18 */
19 public final class Router : Thread
20 {
21     private Identity identity;
22     private Table routingTable;
23 
24     private Advertiser advertiser;
25 
26     private Engine engine;
27 
28     this(Engine engine, Identity identity)
29     {
30         /* Set the thread's worker function */
31         super(&worker);
32 
33         
34 
35         this.engine = engine;
36         this.identity = identity;
37 
38         /* Create a new routing table */
39         routingTable = new Table();
40 
41         /* Initialize the advertiser */
42         initAdvertiser();
43     }
44 
45     
46 
47     private void initAdvertiser()
48     {
49         advertiser = new Advertiser(this);
50     }
51 
52     private void worker()
53     {
54         /* TODO: Implement me */
55 
56         
57         while(true)
58         {
59             /* Update our-self-route creationTime */
60             routingTable.lockTable();
61             Route selfRoute = routingTable.lookup(identity.getKeys().publicKey);
62             selfRoute.updateCreationTime(Clock.currTime());
63             routingTable.unlockTable();
64 
65             //TODO
66 
67 
68             // /* Cycle through the in queue of each link */
69             // Link[] links = getLinks();
70             // foreach(Link link; links)
71             // {
72             //     /* Check if the in-queue has anything in it */
73             //     if(link.hasInQueue())
74             //     {
75             //         Message message = link.popInQueue();
76             //         process(message);
77             //     }
78             // }
79 
80             // process(null);
81 
82             /* Check if any routes need to be expired */
83             checkRouteExpiration();
84 
85             
86             
87             string routeInfo;
88             routingTable.lockTable();
89             Route[] routes = routingTable.getRoutes();
90             routingTable.unlockTable();
91             foreach(Route route; routes)
92             {
93                 routeInfo ~= to!(string)(route) ~ "\n";
94             }
95 
96             gprintln("<<<<<<< Routing table state "~getIdentity().getKeys().publicKey~">>>>>>>\n"~routeInfo);
97 
98 
99             sleep(dur!("seconds")(5));
100         }
101     }
102 
103     private void checkRouteExpiration()
104     {
105         routingTable.lockTable();
106         Route[] routes = routingTable.getRoutes();
107         foreach(Route route; routes)
108         {
109             if(route.isExpired())
110             {
111                 routingTable.removeRoute(route);
112                 gprintln("Expired route "~to!(string)(route)~", removing...", DebugType.WARNING);
113             }
114         }
115         routingTable.unlockTable();
116     }
117 
118     
119 
120     public Engine getEngine()
121     {
122         return engine;
123     }
124 
125     public Table getTable()
126     {
127         return routingTable;
128     }
129 
130     public Identity getIdentity()
131     {
132         return identity;
133     }
134 
135     public void launch()
136     {
137         start();
138 
139         /* Launch the routes advertiser */
140         advertiser.launch();
141     }
142 }