datawire_mdk 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/mdk.rb ADDED
@@ -0,0 +1,962 @@
1
+ # Quark 1.0.406 run at 2016-08-31 13:21:53.028839
2
+ module Quark
3
+ require "quark"
4
+ def self.mdk; Mdk; end
5
+ module Mdk
6
+ require "datawire-quark-core"
7
+ require_relative 'quark/reflect' # 0 ('quark',) ()
8
+ require_relative 'mdk_runtime' # 0 () ()
9
+ require_relative 'datawire_mdk_md' # 0 () ()
10
+ require_relative 'mdk_discovery' # 0 () ()
11
+ require_relative 'quark' # 0 () ()
12
+ require_relative 'mdk_tracing' # 0 () ()
13
+ require_relative 'quark/concurrent' # 0 ('quark',) ()
14
+ require_relative 'mdk_introspection' # 0 () ()
15
+ require_relative 'mdk_discovery/protocol' # 0 ('mdk_discovery',) ()
16
+ require_relative 'mdk_discovery/synapse' # 0 ('mdk_discovery',) ()
17
+ require_relative 'mdk_protocol' # 0 () ()
18
+ require_relative 'mdk_runtime/promise' # 0 ('mdk_runtime',) ()
19
+ require_relative 'mdk_util' # 0 () ()
20
+
21
+
22
+ def self._get(env, name, value)
23
+
24
+ return env.var(name).orElseGet(value)
25
+
26
+
27
+ nil
28
+ end
29
+
30
+ ##
31
+ # Create an unstarted instance of the MDK.
32
+
33
+ def self.init()
34
+
35
+ return ::Quark.mdk.MDKImpl.new(::Quark.mdk_runtime.defaultRuntime())
36
+
37
+
38
+ nil
39
+ end
40
+
41
+ ##
42
+ # Create a started instance of the MDK. This is equivalent to
43
+ # calling init() followed by start() on the resulting instance.
44
+ #
45
+
46
+ def self.start()
47
+
48
+ m = ::Quark.mdk.init()
49
+ m.start()
50
+ return m
51
+
52
+
53
+ nil
54
+ end
55
+
56
+ def self.MDK; MDK; end
57
+ ##
58
+ # The MDK API consists of two interfaces: MDK and Session. The
59
+ # MDK interface holds globally scoped APIs and state associated
60
+ # with the microservice. The Session interface holds locally
61
+ # scoped APIs and state. A Session must be used sequentially.
62
+ #
63
+ # The MDK instance is responsible for communicating with
64
+ # foundational services like discovery and tracing.
65
+ #
66
+ # There will typically be one MDK instance for the entire
67
+ # process, and one instance of the Session object per
68
+ # thread/channel/request depending on how the MDK is integrated
69
+ # and used within the application framework of choice.
70
+ #
71
+
72
+ class MDK < ::DatawireQuarkCore::QuarkObject
73
+ extend ::DatawireQuarkCore::Static
74
+
75
+ static CONTEXT_HEADER: -> { "X-MDK-Context" }
76
+ static mdk_MDK_ref: -> { nil }
77
+
78
+
79
+
80
+ def initialize()
81
+ self.__init_fields__
82
+
83
+ nil
84
+ end
85
+
86
+
87
+
88
+
89
+ ##
90
+ # Start the MDK. An MDK instance will not communicate with
91
+ # foundational services unless it is started.
92
+ #
93
+
94
+ def start()
95
+ raise NotImplementedError, '`MDK.start` is an abstract method'
96
+
97
+ nil
98
+ end
99
+
100
+ ##
101
+ # Stop the MDK. When the MDK stops unregisters any service
102
+ # endpoints from the discovery system. This should always
103
+ # be done prior to process exit in order to propogate node
104
+ # shutdowns in realtime rather than waiting for heartbeats
105
+ # to detect node departures.
106
+ #
107
+
108
+ def stop()
109
+ raise NotImplementedError, '`MDK.stop` is an abstract method'
110
+
111
+ nil
112
+ end
113
+
114
+ ##
115
+ # Registers a service endpoint with the discovery
116
+ # system. This can be called at any point, however
117
+ # registered endpoints will not be advertised to the
118
+ # discovery system until the MDK is started.
119
+ #
120
+
121
+ def register(service, version, address)
122
+ raise NotImplementedError, '`MDK.register` is an abstract method'
123
+
124
+ nil
125
+ end
126
+
127
+ ##
128
+ # Creates a new Session. A Session created in this way will
129
+ # result in a new distributed trace. This should therefore
130
+ # be used primarily by edge services. Intermediary and
131
+ # foundational services should make use of
132
+ # join(encodedContext) in order to preserve distributed
133
+ # traces.
134
+ #
135
+
136
+ def session()
137
+ raise NotImplementedError, '`MDK.session` is an abstract method'
138
+
139
+ nil
140
+ end
141
+
142
+ ##
143
+ # Create a new Session and join it to a distributed trace.
144
+ #
145
+
146
+ def join(encodedContext)
147
+ raise NotImplementedError, '`MDK.join` is an abstract method'
148
+
149
+ nil
150
+ end
151
+
152
+ def __init_fields__()
153
+
154
+
155
+ nil
156
+ end
157
+
158
+
159
+ end
160
+ MDK.unlazy_statics
161
+
162
+ def self.Session; Session; end
163
+ ##
164
+ # A session provides a lightweight sequential context that a
165
+ # microservice can use in the context of any application
166
+ # framework in order to manage its interactions with other
167
+ # microservices. It provides simple APIs for service
168
+ # resolution, distributed tracing, and circuit breakers.
169
+ #
170
+ # A microservices architecture enables small self contained
171
+ # units of business logic to be implemented by separate teams
172
+ # working on isolated services based on the languages and
173
+ # frameworks best suited for their problem domain.
174
+ #
175
+ # Any given microservice will contain sequential business logic
176
+ # implemented in a variety of ways depending on the application
177
+ # framework chosen. For example it may be a long running
178
+ # thread, a simple blocking request handler, or a chained
179
+ # series of reactive handlers in an async environment.
180
+ #
181
+ # For the most part this business logic can be implemented
182
+ # exactly as prescribed by the application framework of choice,
183
+ # however in a microservices architecture, some special care
184
+ # needs to be taken when this business logic interacts with
185
+ # other microservices.
186
+ #
187
+ # Because microservices are updated with much higher frequency
188
+ # than normal web applications, the interactions between them
189
+ # form key points that require extra care beyond normal web
190
+ # interactions in order to avoid creating a system that is both
191
+ # extremely fragile, unreliable, and opaque.
192
+ #
193
+ # Realtime service resolution, distributed tracing, and
194
+ # resilience heuristics such as circuit breakers provide the
195
+ # foundational behavior required at these interaction
196
+ # points. These capabilites must be combined with the defensive
197
+ # coding practice of intelligent fallback behavior when remote
198
+ # services are unavailable or misbehaving, in order to build a
199
+ # robust microservice application.
200
+ #
201
+ # Because of this, a session is expected to be created and made
202
+ # available to all business logic within a given microservice,
203
+ # e.g. on a per request basis, as a thread local, part of a
204
+ # context object, etc depending on the application framework of
205
+ # choice.
206
+ #
207
+
208
+ class Session < ::DatawireQuarkCore::QuarkObject
209
+ extend ::DatawireQuarkCore::Static
210
+
211
+ static mdk_Session_ref: -> { nil }
212
+
213
+
214
+
215
+ def initialize()
216
+ self.__init_fields__
217
+
218
+ nil
219
+ end
220
+
221
+
222
+
223
+
224
+ ##
225
+ # Grabs the encoded context.
226
+
227
+ def inject()
228
+ raise NotImplementedError, '`Session.inject` is an abstract method'
229
+
230
+ nil
231
+ end
232
+
233
+ ##
234
+ # Returns an externalized representation of the distributed session.
235
+
236
+ def externalize()
237
+ raise NotImplementedError, '`Session.externalize` is an abstract method'
238
+
239
+ nil
240
+ end
241
+
242
+ ##
243
+ # Record a log entry at the CRITICAL logging level.
244
+
245
+ def critical(category, text)
246
+ raise NotImplementedError, '`Session.critical` is an abstract method'
247
+
248
+ nil
249
+ end
250
+
251
+ ##
252
+ # Record a log entry at the ERROR logging level.
253
+
254
+ def error(category, text)
255
+ raise NotImplementedError, '`Session.error` is an abstract method'
256
+
257
+ nil
258
+ end
259
+
260
+ ##
261
+ # Record a log entry at the WARN logging level.
262
+
263
+ def warn(category, text)
264
+ raise NotImplementedError, '`Session.warn` is an abstract method'
265
+
266
+ nil
267
+ end
268
+
269
+ ##
270
+ # Record a log entry at the INFO logging level.
271
+
272
+ def info(category, text)
273
+ raise NotImplementedError, '`Session.info` is an abstract method'
274
+
275
+ nil
276
+ end
277
+
278
+ ##
279
+ # Record a log entry at the DEBUG logging level.
280
+
281
+ def debug(category, text)
282
+ raise NotImplementedError, '`Session.debug` is an abstract method'
283
+
284
+ nil
285
+ end
286
+
287
+ ##
288
+ # EXPERIMENTAL: Set the logging level for the session.
289
+
290
+ def trace(level)
291
+ raise NotImplementedError, '`Session.trace` is an abstract method'
292
+
293
+ nil
294
+ end
295
+
296
+ ##
297
+ # EXPERIMENTAL; requires MDK_EXPERIMENTAL=1 environment variable to
298
+ # function.
299
+ #
300
+ # Override service resolution for the current distributed
301
+ # session. All attempts to resolve *service*, *version*
302
+ # will be replaced with an attempt to resolve *target*,
303
+ # *targetVersion*. This effect will be propogated to any
304
+ # downstream services involved in the distributed session.
305
+ #
306
+
307
+ def route(service, version, target, targetVersion)
308
+ raise NotImplementedError, '`Session.route` is an abstract method'
309
+
310
+ nil
311
+ end
312
+
313
+ ##
314
+ # Locate a compatible service instance.
315
+ #
316
+
317
+ def resolve(service, version)
318
+ raise NotImplementedError, '`Session.resolve` is an abstract method'
319
+
320
+ nil
321
+ end
322
+
323
+ ##
324
+ # Locate a compatible service instance with a non-default timeout.
325
+ #
326
+
327
+ def resolve_until(service, version, timeout)
328
+ raise NotImplementedError, '`Session.resolve_until` is an abstract method'
329
+
330
+ nil
331
+ end
332
+
333
+ ##
334
+ # Locate a compatible service instance asynchronously. The result is returned as a promise.
335
+ #
336
+
337
+ def resolve_async(service, version)
338
+ raise NotImplementedError, '`Session.resolve_async` is an abstract method'
339
+
340
+ nil
341
+ end
342
+
343
+ ##
344
+ # Start an interaction with a remote service.
345
+ #
346
+ # The session tracks any nodes resolved during an
347
+ # interactin with a remote service.
348
+ #
349
+ # The service resolution API permits a compatible instance
350
+ # of the service to be located. In addition, it tracks
351
+ # which exact instances are in use during any
352
+ # interaction. Should the interaction fail, circuit breaker
353
+ # state is updated for those nodes, and all involved
354
+ # instances involved are reported to the tracing services.
355
+ #
356
+ # This permits realtime reporting of integration issues
357
+ # when services are updated, and also allows circuit
358
+ # breakers to mitigate the impact of any such issues.
359
+ #
360
+
361
+ def start_interaction()
362
+ raise NotImplementedError, '`Session.start_interaction` is an abstract method'
363
+
364
+ nil
365
+ end
366
+
367
+ ##
368
+ # Record an interaction as failed.
369
+ #
370
+ # This will update circuit breaker state for the remote
371
+ # nodes, as well as reporting all nodes involved to the
372
+ # tracing system.
373
+ #
374
+
375
+ def fail_interaction(message)
376
+ raise NotImplementedError, '`Session.fail_interaction` is an abstract method'
377
+
378
+ nil
379
+ end
380
+
381
+ ##
382
+ # Finish an interaction.
383
+ #
384
+ # This marks an interaction as completed.
385
+ #
386
+
387
+ def finish_interaction()
388
+ raise NotImplementedError, '`Session.finish_interaction` is an abstract method'
389
+
390
+ nil
391
+ end
392
+
393
+ ##
394
+ # This is a convenience API that will perform
395
+ # start_interaction() followed by callable(ssn) followed by
396
+ # finish_interaction().
397
+ #
398
+ #
399
+
400
+ def interact(callable)
401
+ raise NotImplementedError, '`Session.interact` is an abstract method'
402
+
403
+ nil
404
+ end
405
+
406
+ def __init_fields__()
407
+
408
+
409
+ nil
410
+ end
411
+
412
+
413
+ end
414
+ Session.unlazy_statics
415
+
416
+ def self.MDKImpl; MDKImpl; end
417
+ class MDKImpl < ::DatawireQuarkCore::QuarkObject
418
+ attr_accessor :logger, :_runtime, :_disco, :_discoSource, :_tracer, :procUUID, :_running
419
+ extend ::DatawireQuarkCore::Static
420
+
421
+ static mdk_MDKImpl_ref: -> { nil }
422
+ static CONTEXT_HEADER: -> { "X-MDK-Context" }
423
+
424
+
425
+
426
+ def initialize(runtime)
427
+
428
+ self.__init_fields__
429
+ @_runtime = runtime
430
+ if (!((runtime).dependencies.hasService("failurepolicy_factory")))
431
+ (runtime).dependencies.registerService("failurepolicy_factory", ::Quark.mdk_discovery.CircuitBreakerFactory.new(runtime))
432
+ end
433
+ @_disco = ::Quark.mdk_discovery.Discovery.new(runtime)
434
+ env = runtime.getEnvVarsService()
435
+ token = env.var("DATAWIRE_TOKEN").orElseGet("")
436
+ discoFactory = self.getDiscoveryFactory(env)
437
+ @_discoSource = discoFactory.create(@_disco, runtime)
438
+ if (discoFactory.isRegistrar())
439
+ (runtime).dependencies.registerService("discovery_registrar", @_discoSource)
440
+ end
441
+ if ((token) != (""))
442
+ tracingURL = ::Quark.mdk._get(env, "MDK_TRACING_URL", "wss://tracing.datawire.io/ws/v1")
443
+ tracingQueryURL = ::Quark.mdk._get(env, "MDK_TRACING_API_URL", "https://tracing.datawire.io/api/v1/logs")
444
+ @_tracer = ::Quark.mdk_tracing.Tracer.new(runtime)
445
+ (@_tracer).url = tracingURL
446
+ (@_tracer).queryURL = tracingQueryURL
447
+ (@_tracer).token = token
448
+ @_tracer.initContext()
449
+ end
450
+
451
+ nil
452
+ end
453
+
454
+
455
+
456
+
457
+ ##
458
+ # Choose DiscoverySource based on environment variables.
459
+
460
+ def getDiscoveryFactory(env)
461
+
462
+ config = env.var("MDK_DISCOVERY_SOURCE").orElseGet("")
463
+ if ((config) == (""))
464
+ config = ("datawire:") + (::Quark.mdk_introspection.DatawireToken.getToken(env))
465
+ end
466
+ result = ::DatawireQuarkCore.cast(nil) { ::Quark.mdk_discovery.DiscoverySourceFactory }
467
+ if ((config).start_with?("datawire:"))
468
+ result = ::Quark.mdk_discovery.protocol.DiscoClientFactory.new((config)[(9)...((config).size)])
469
+ else
470
+ if ((config).start_with?("synapse:path="))
471
+ result = ::Quark.mdk_discovery.synapse.Synapse.new((config)[(13)...((config).size)])
472
+ else
473
+ raise (("Unknown MDK discovery source: ") + (config))
474
+ end
475
+ end
476
+ return result
477
+
478
+ nil
479
+ end
480
+
481
+ def _timeout()
482
+
483
+ return 10.0
484
+
485
+ nil
486
+ end
487
+
488
+ def start()
489
+
490
+ (self)._running = true
491
+ (@_runtime).dispatcher.startActor(@_disco)
492
+ (@_runtime).dispatcher.startActor(@_discoSource)
493
+
494
+ nil
495
+ end
496
+
497
+ def stop()
498
+
499
+ (self)._running = false
500
+ (@_runtime).dispatcher.stopActor(@_disco)
501
+ (@_runtime).dispatcher.stopActor(@_discoSource)
502
+ @_tracer.stop()
503
+ @_runtime.stop()
504
+
505
+ nil
506
+ end
507
+
508
+ def register(service, version, address)
509
+
510
+ node = ::Quark.mdk_discovery.Node.new()
511
+ (node).service = service
512
+ (node).version = version
513
+ (node).address = address
514
+ (node).properties = {"datawire_nodeId" => @procUUID}
515
+ @_disco.register(node)
516
+
517
+ nil
518
+ end
519
+
520
+ def session()
521
+
522
+ return ::Quark.mdk.SessionImpl.new(self, nil)
523
+
524
+ nil
525
+ end
526
+
527
+ def join(encodedContext)
528
+
529
+ return ::Quark.mdk.SessionImpl.new(self, encodedContext)
530
+
531
+ nil
532
+ end
533
+
534
+ def _getClass()
535
+
536
+ return "mdk.MDKImpl"
537
+
538
+ nil
539
+ end
540
+
541
+ def _getField(name)
542
+
543
+ if ((name) == ("CONTEXT_HEADER"))
544
+ return ::Quark.mdk.MDK.CONTEXT_HEADER
545
+ end
546
+ if ((name) == ("logger"))
547
+ return (self).logger
548
+ end
549
+ if ((name) == ("_runtime"))
550
+ return (self)._runtime
551
+ end
552
+ if ((name) == ("_disco"))
553
+ return (self)._disco
554
+ end
555
+ if ((name) == ("_discoSource"))
556
+ return (self)._discoSource
557
+ end
558
+ if ((name) == ("_tracer"))
559
+ return (self)._tracer
560
+ end
561
+ if ((name) == ("procUUID"))
562
+ return (self).procUUID
563
+ end
564
+ if ((name) == ("_running"))
565
+ return (self)._running
566
+ end
567
+ return nil
568
+
569
+ nil
570
+ end
571
+
572
+ def _setField(name, value)
573
+
574
+ if ((name) == ("logger"))
575
+ (self).logger = value
576
+ end
577
+ if ((name) == ("_runtime"))
578
+ (self)._runtime = ::DatawireQuarkCore.cast(value) { ::Quark.mdk_runtime.MDKRuntime }
579
+ end
580
+ if ((name) == ("_disco"))
581
+ (self)._disco = ::DatawireQuarkCore.cast(value) { ::Quark.mdk_discovery.Discovery }
582
+ end
583
+ if ((name) == ("_discoSource"))
584
+ (self)._discoSource = ::DatawireQuarkCore.cast(value) { ::Quark.mdk_discovery.DiscoverySource }
585
+ end
586
+ if ((name) == ("_tracer"))
587
+ (self)._tracer = ::DatawireQuarkCore.cast(value) { ::Quark.mdk_tracing.Tracer }
588
+ end
589
+ if ((name) == ("procUUID"))
590
+ (self).procUUID = ::DatawireQuarkCore.cast(value) { ::String }
591
+ end
592
+ if ((name) == ("_running"))
593
+ (self)._running = ::DatawireQuarkCore.cast(value) { ::Object }
594
+ end
595
+
596
+ nil
597
+ end
598
+
599
+ def __init_fields__()
600
+
601
+ self.logger = ::Quark.quark._getLogger("mdk")
602
+ self._runtime = nil
603
+ self._disco = nil
604
+ self._discoSource = nil
605
+ self._tracer = nil
606
+ self.procUUID = ::Quark.quark.concurrent.Context.runtime().uuid()
607
+ self._running = false
608
+
609
+ nil
610
+ end
611
+
612
+
613
+ end
614
+ MDKImpl.unlazy_statics
615
+
616
+ def self.SessionImpl; SessionImpl; end
617
+ class SessionImpl < ::DatawireQuarkCore::QuarkObject
618
+ attr_accessor :_mdk, :_resolved, :_context, :_experimental
619
+ extend ::DatawireQuarkCore::Static
620
+
621
+ static _levels: -> { {"CRITICAL" => 0, "ERROR" => 1, "WARN" => 2, "INFO" => 3, "DEBUG" => 4} }
622
+ static mdk_SessionImpl_ref: -> { nil }
623
+ static quark_List_mdk_discovery_Node__ref: -> { nil }
624
+ static quark_List_quark_Map_quark_String_quark_String___ref: -> { nil }
625
+ static quark_List_quark_String__ref: -> { nil }
626
+ static quark_Map_quark_String_quark_int__ref: -> { nil }
627
+ static quark_Map_quark_String_quark_List_quark_Map_quark_String_quark_String____ref: -> { nil }
628
+ static quark_Map_quark_String_quark_String__ref: -> { nil }
629
+
630
+
631
+
632
+ def initialize(mdk, encodedContext)
633
+
634
+ self.__init_fields__
635
+ @_experimental = ((mdk)._runtime.getEnvVarsService().var("MDK_EXPERIMENTAL").orElseGet("")) != ("")
636
+ @_mdk = mdk
637
+ encodedContext = ::DatawireQuarkCore.cast(encodedContext) { ::String }
638
+ if (((encodedContext) == (nil)) || ((encodedContext) == ("")))
639
+ @_context = ::Quark.mdk_protocol.SharedContext.new()
640
+ else
641
+ ctx = ::Quark.mdk_protocol.SharedContext.decode(encodedContext)
642
+ @_context = ctx.start_span()
643
+ end
644
+
645
+ nil
646
+ end
647
+
648
+
649
+
650
+
651
+ def get(property)
652
+
653
+ return ((@_context).properties)[property]
654
+
655
+ nil
656
+ end
657
+
658
+ def set(property, value)
659
+
660
+ ((@_context).properties)[property] = (value)
661
+
662
+ nil
663
+ end
664
+
665
+ def has(property)
666
+
667
+ return ((@_context).properties).key?(property)
668
+
669
+ nil
670
+ end
671
+
672
+ def route(service, version, target, targetVersion)
673
+
674
+ routes = nil
675
+ if (!(self.has("routes")))
676
+ routes = {}
677
+ self.set("routes", routes)
678
+ else
679
+ routes = ::DatawireQuarkCore.cast(self.get("routes")) { ::Hash }
680
+ end
681
+ targets = nil
682
+ if ((routes).key?(service))
683
+ targets = (routes)[service]
684
+ else
685
+ targets = ::DatawireQuarkCore::List.new([])
686
+ (routes)[service] = (targets)
687
+ end
688
+ (targets) << ({"version" => version, "target" => target, "targetVersion" => targetVersion})
689
+
690
+ nil
691
+ end
692
+
693
+ def trace(level)
694
+
695
+ self.set("trace", level)
696
+
697
+ nil
698
+ end
699
+
700
+ def self._level(level)
701
+
702
+ if ((::Quark.mdk.SessionImpl._levels).key?(level))
703
+ return (::Quark.mdk.SessionImpl._levels)[level]
704
+ else
705
+ return 0
706
+ end
707
+
708
+ nil
709
+ end
710
+
711
+ def _enabled(level)
712
+
713
+ ilevel = ::Quark.mdk.SessionImpl._level("INFO")
714
+ if (self.has("trace"))
715
+ ilevel = ::Quark.mdk.SessionImpl._level(::DatawireQuarkCore.cast(self.get("trace")) { ::String })
716
+ end
717
+ return (::Quark.mdk.SessionImpl._level(level)) <= (ilevel)
718
+
719
+ nil
720
+ end
721
+
722
+ def _log(level, category, text)
723
+
724
+ if (((@_mdk)._tracer) != (nil))
725
+ (@_mdk)._tracer.setContext(@_context)
726
+ (@_mdk)._tracer.log((@_mdk).procUUID, level, category, text)
727
+ end
728
+
729
+ nil
730
+ end
731
+
732
+ def critical(category, text)
733
+
734
+ if (self._enabled("CRITICAL"))
735
+ (@_mdk).logger.error(((category) + (": ")) + (text))
736
+ self._log("CRITICAL", category, text)
737
+ end
738
+
739
+ nil
740
+ end
741
+
742
+ def error(category, text)
743
+
744
+ if (self._enabled("ERROR"))
745
+ (@_mdk).logger.error(((category) + (": ")) + (text))
746
+ self._log("ERROR", category, text)
747
+ end
748
+
749
+ nil
750
+ end
751
+
752
+ def warn(category, text)
753
+
754
+ if (self._enabled("WARN"))
755
+ (@_mdk).logger.warn(((category) + (": ")) + (text))
756
+ self._log("WARN", category, text)
757
+ end
758
+
759
+ nil
760
+ end
761
+
762
+ def info(category, text)
763
+
764
+ if (self._enabled("INFO"))
765
+ (@_mdk).logger.info(((category) + (": ")) + (text))
766
+ self._log("INFO", category, text)
767
+ end
768
+
769
+ nil
770
+ end
771
+
772
+ def debug(category, text)
773
+
774
+ if (self._enabled("DEBUG"))
775
+ (@_mdk).logger.debug(((category) + (": ")) + (text))
776
+ self._log("DEBUG", category, text)
777
+ end
778
+
779
+ nil
780
+ end
781
+
782
+ def _resolve(service, version)
783
+
784
+ if (@_experimental)
785
+ routes = ::DatawireQuarkCore.cast(self.get("routes")) { ::Hash }
786
+ if (((routes) != (nil)) && ((routes).key?(service)))
787
+ targets = (routes)[service]
788
+ idx = 0
789
+ while ((idx) < ((targets).size)) do
790
+ target = (targets)[idx]
791
+ if (::Quark.mdk_util.versionMatch((target)["version"], version))
792
+ service = (target)["target"]
793
+ version = (target)["targetVersion"]
794
+ break
795
+ end
796
+ idx = (idx) + (1)
797
+ end
798
+ end
799
+ end
800
+ return (@_mdk)._disco._resolve(service, version).andThen(::Quark.quark._BoundMethod.new(self, "_resolvedCallback", ::DatawireQuarkCore::List.new([])))
801
+
802
+ nil
803
+ end
804
+
805
+ def resolve_async(service, version)
806
+
807
+ return ::Quark.mdk_util.toNativePromise(self._resolve(service, version))
808
+
809
+ nil
810
+ end
811
+
812
+ def resolve(service, version)
813
+
814
+ return self.resolve_until(service, version, @_mdk._timeout())
815
+
816
+ nil
817
+ end
818
+
819
+ def resolve_until(service, version, timeout)
820
+
821
+ return ::DatawireQuarkCore.cast(::Quark.mdk_util.WaitForPromise.wait(self._resolve(service, version), timeout, (((("service ") + (service)) + ("(")) + (version)) + (")"))) { ::Quark.mdk_discovery.Node }
822
+
823
+ nil
824
+ end
825
+
826
+ def _resolvedCallback(result)
827
+
828
+ (@_resolved) << (result)
829
+ return result
830
+
831
+ nil
832
+ end
833
+
834
+ def start_interaction()
835
+
836
+ @_resolved = ::DatawireQuarkCore::List.new([])
837
+
838
+ nil
839
+ end
840
+
841
+ def inject()
842
+
843
+ return self.externalize()
844
+
845
+ nil
846
+ end
847
+
848
+ def externalize()
849
+
850
+ result = @_context.encode()
851
+ @_context.tick()
852
+ return result
853
+
854
+ nil
855
+ end
856
+
857
+ def fail_interaction(message)
858
+
859
+ suspects = @_resolved
860
+ @_resolved = ::DatawireQuarkCore::List.new([])
861
+ involved = ::DatawireQuarkCore::List.new([])
862
+ idx = 0
863
+ while ((idx) < ((suspects).size)) do
864
+ node = (suspects)[idx]
865
+ idx = (idx) + (1)
866
+ (involved) << (node.toString())
867
+ node.failure()
868
+ end
869
+ text = ((("involved: ") + ((involved).join(", "))) + ("\n\n")) + (message)
870
+ self.error("interaction failure", text)
871
+
872
+ nil
873
+ end
874
+
875
+ def finish_interaction()
876
+
877
+ nodes = @_resolved
878
+ @_resolved = ::DatawireQuarkCore::List.new([])
879
+ idx = 0
880
+ while ((idx) < ((nodes).size)) do
881
+ node = (nodes)[idx]
882
+ node.success()
883
+ idx = (idx) + (1)
884
+ end
885
+
886
+ nil
887
+ end
888
+
889
+ def interact(cmd)
890
+
891
+ self.start_interaction()
892
+ (cmd).call(self)
893
+ self.finish_interaction()
894
+
895
+ nil
896
+ end
897
+
898
+ def _getClass()
899
+
900
+ return "mdk.SessionImpl"
901
+
902
+ nil
903
+ end
904
+
905
+ def _getField(name)
906
+
907
+ if ((name) == ("_levels"))
908
+ return ::Quark.mdk.SessionImpl._levels
909
+ end
910
+ if ((name) == ("_mdk"))
911
+ return (self)._mdk
912
+ end
913
+ if ((name) == ("_resolved"))
914
+ return (self)._resolved
915
+ end
916
+ if ((name) == ("_context"))
917
+ return (self)._context
918
+ end
919
+ if ((name) == ("_experimental"))
920
+ return (self)._experimental
921
+ end
922
+ return nil
923
+
924
+ nil
925
+ end
926
+
927
+ def _setField(name, value)
928
+
929
+ if ((name) == ("_levels"))
930
+ ::Quark.mdk.SessionImpl._levels = ::DatawireQuarkCore.cast(value) { ::Hash }
931
+ end
932
+ if ((name) == ("_mdk"))
933
+ (self)._mdk = ::DatawireQuarkCore.cast(value) { ::Quark.mdk.MDKImpl }
934
+ end
935
+ if ((name) == ("_resolved"))
936
+ (self)._resolved = ::DatawireQuarkCore.cast(value) { ::DatawireQuarkCore::List }
937
+ end
938
+ if ((name) == ("_context"))
939
+ (self)._context = ::DatawireQuarkCore.cast(value) { ::Quark.mdk_protocol.SharedContext }
940
+ end
941
+ if ((name) == ("_experimental"))
942
+ (self)._experimental = ::DatawireQuarkCore.cast(value) { ::Object }
943
+ end
944
+
945
+ nil
946
+ end
947
+
948
+ def __init_fields__()
949
+
950
+ self._mdk = nil
951
+ self._resolved = ::DatawireQuarkCore::List.new([])
952
+ self._context = nil
953
+ self._experimental = false
954
+
955
+ nil
956
+ end
957
+
958
+
959
+ end
960
+ SessionImpl.unlazy_statics
961
+ end # module Mdk
962
+ end # module Quark