1 module tagion.tools.shell.shelloptions;
2 
3 @safe:
4 
5 import tagion.services.options : contract_sock_addr;
6 import tagion.utils.JSONCommon;
7 import std.format;
8 
9 enum mode0_prefix = "Node_%d_";
10 
11 import std.exception;
12 
13 struct ShellOptions {
14     string shell_uri;
15     string shell_api_prefix;
16     string contract_endpoint;
17     string dart_endpoint;
18     string dartcache_endpoint;
19     string tagion_subscription_addr;
20     string bullseye_endpoint;
21     string i2p_endpoint;
22     string sysinfo_endpoint;
23     string default_i2p_wallet;
24     string default_i2p_wallet_pin;
25     uint number_of_nodes;
26     string contract_addr_prefix;
27     string dart_addr_prefix;
28 
29     void setDefault() nothrow {
30         contract_addr_prefix = "CONTRACT_";
31         dart_addr_prefix = "DART_";
32         shell_uri = "http://0.0.0.0:8080";
33         tagion_subscription_addr = contract_sock_addr("SUBSCRIPTION_");
34         shell_api_prefix = "/api/v1";
35         contract_endpoint = "/contract";
36         dart_endpoint = "/dart";
37         dartcache_endpoint = "/dartcache";
38         bullseye_endpoint = "/bullseye";
39         i2p_endpoint = "/invoice2pay";
40         sysinfo_endpoint = "/sysinfo";
41         default_i2p_wallet = "./wallets/wallet1.json";
42         default_i2p_wallet_pin = "0001";
43         number_of_nodes = 5;
44     }
45 
46     /// Gives a new node address each time it is called
47     string node_contract_addr() nothrow {
48         uint node_number = contract_robin.next(number_of_nodes);
49         return contract_sock_addr(assumeWontThrow(format(mode0_prefix, node_number)) ~ contract_addr_prefix);
50     }
51 
52     /// Gives a new node address each time it is called
53     string node_dart_addr() nothrow {
54         uint node_number = dart_robin.next(number_of_nodes);
55         return contract_sock_addr(assumeWontThrow(format(mode0_prefix, node_number)) ~ dart_addr_prefix);
56     }
57 
58     mixin JSONCommon;
59     mixin JSONConfig;
60 }
61 
62 final synchronized class RoundRobin {
63     import core.atomic;
64 
65     protected uint counter;
66     uint next(const uint number_of_nodes) nothrow {
67         if ((counter.atomicLoad + 1) >= number_of_nodes) {
68             counter.atomicStore(0);
69         }
70         else {
71             counter.atomicOp!"+="(1);
72         }
73         return counter;
74     }
75 }
76 
77 shared RoundRobin contract_robin;
78 shared RoundRobin dart_robin;
79 shared static this() {
80     contract_robin = new RoundRobin();
81     dart_robin = new RoundRobin();
82 }