1 /// Options for tagionwave services,
2 /// Publicly imports all service options
3 module tagion.services.options;
4 import std.format;
5 import std.range;
6 import std.traits;
7 
8 import tagion.basic.dir;
9 
10 /// This function should be renamed
11 /// Initially there it was only intended to be used for the contract address for the inputvalidator
12 static immutable(string) contract_sock_addr(const string prefix = "") @safe nothrow {
13     import std.exception : assumeWontThrow;
14 
15     version (linux) {
16         return assumeWontThrow(format("abstract://%sNEUEWELLE", prefix));
17     }
18     else version (Posix) {
19         import std.path;
20 
21         return "ipc://" ~ buildPath(base_dir.run, assumeWontThrow(format("%stagionwave_contract.sock", prefix)));
22     }
23     else {
24         assert(0, "Unsupported platform");
25     }
26 }
27 
28 enum NetworkMode {
29     INTERNAL,
30     LOCAL,
31     PUB
32 }
33 
34 @safe
35 struct WaveOptions {
36     import tagion.utils.JSONCommon;
37 
38     NetworkMode network_mode = NetworkMode.INTERNAL;
39     uint number_of_nodes = 5;
40     string prefix_format = "Node_%s_";
41     bool fail_fast = false;
42     mixin JSONCommon;
43 }
44 
45 @safe
46 struct TaskNames {
47     public import tagion.utils.JSONCommon;
48 
49     string program = "tagion";
50     string supervisor = "supervisor";
51     string inputvalidator = "inputvalidator";
52     string dart = "dart";
53     string hirpc_verifier = "hirpc_verifier";
54     string collector = "collector";
55     string transcript = "transcript";
56     string tvm = "tvm";
57     string epoch_creator = "epoch_creator";
58     string replicator = "replicator";
59     string dart_interface = "dartinterface";
60     string trt = "trt";
61 
62     mixin JSONCommon;
63 
64     /// Set a prefix for the default options
65     this(const string prefix) pure {
66         setPrefix(prefix);
67     }
68 
69     /**
70         Inserts a prefix for all the task_names
71         This function is used in mode 0.
72     */
73     void setPrefix(const string prefix) pure nothrow {
74         import std.exception;
75 
76         alias This = typeof(this);
77         alias FieldsNames = FieldNameTuple!This;
78         static foreach (i, T; Fields!This) {
79             static if (is(T == string)) {
80                 this.tupleof[i] = assumeWontThrow(format("%s%s", prefix, this.tupleof[i]));
81             }
82         }
83     }
84 }
85 
86 /// All options for neuewelle
87 @safe
88 struct Options {
89     import std.json;
90     import tagion.utils.JSONCommon;
91 
92     import tagion.logger.LoggerOptions : LoggerOptions;
93     import tagion.services.DART : DARTOptions;
94     import tagion.services.DARTInterface : DARTInterfaceOptions;
95     import tagion.services.collector : CollectorOptions;
96     import tagion.services.epoch_creator : EpochCreatorOptions;
97     import tagion.services.hirpc_verifier : HiRPCVerifierOptions;
98     import tagion.services.inputvalidator : InputValidatorOptions;
99     import tagion.services.monitor : MonitorOptions;
100     import tagion.services.replicator : ReplicatorOptions;
101     import tagion.services.subscription : SubscriptionServiceOptions;
102     import tagion.services.transcript : TranscriptOptions;
103     import tagion.services.TRTService : TRTOptions;
104 
105     WaveOptions wave;
106     InputValidatorOptions inputvalidator;
107     HiRPCVerifierOptions hirpc_verifier;
108     DARTOptions dart;
109     EpochCreatorOptions epoch_creator;
110     MonitorOptions monitor;
111     ReplicatorOptions replicator;
112     DARTInterfaceOptions dart_interface;
113     SubscriptionServiceOptions subscription;
114     LoggerOptions logger;
115     TRTOptions trt;
116 
117     TaskNames task_names;
118     mixin JSONCommon;
119     mixin JSONConfig;
120     this(ref inout(Options) opt) inout pure nothrow @trusted {
121         foreach (i, ref inout member; opt.tupleof) {
122             this.tupleof[i] = member;
123         }
124     }
125 
126     static Options defaultOptions() nothrow {
127         Options opts;
128         setDefault(opts);
129         return opts;
130     }
131 
132 }
133 
134 @safe
135 void setDefault(Opt)(ref Opt opt) nothrow if (is(Opt == struct)) {
136     static if (__traits(hasMember, Opt, "setDefault")) {
137         opt.setDefault;
138     }
139     static foreach (i, T; Fields!Opt) {
140         static if (is(T == struct)) {
141             setDefault(opt.tupleof[i]);
142         }
143     }
144 }
145 
146 @safe
147 void setPrefix(Opt)(ref Opt opt, string prefix) nothrow if (is(Opt == struct)) {
148     static if (__traits(hasMember, Opt, "setPrefix")) {
149         opt.setPrefix(prefix);
150     }
151     static foreach (i, T; Fields!Opt) {
152         static if (is(T == struct)) {
153             setPrefix(opt.tupleof[i], prefix);
154         }
155     }
156 }
157 
158 @safe
159 unittest {
160     import std.stdio;
161 
162     enum prefix = "NodeX";
163     Options opt = Options.defaultOptions;
164     assert(opt.task_names.program[0 .. prefix.length] != prefix);
165     assert(opt.task_names.transcript[0 .. prefix.length] != prefix);
166 
167     opt.task_names.setPrefix(prefix);
168     immutable sub_opt = Options(opt);
169     assert(sub_opt.task_names.program[0 .. prefix.length] == prefix);
170     assert(sub_opt.task_names.transcript[0 .. prefix.length] == prefix);
171 }