def test_invoke_progressive_result(self): handler = ApplicationSession() MockTransport(handler) @inlineCallbacks def bing(details=None): self.assertTrue(details is not None) self.assertTrue(details.progress is not None) for i in range(10): details.progress(i) yield succeed(i) returnValue(42) progressive = list(map(lambda _: Deferred(), range(10))) def progress(arg): progressive[arg].callback(arg) # see MockTransport, must start with "com.myapp.myproc" yield handler.register( bing, u'com.myapp.myproc2', types.RegisterOptions(details_arg='details'), ) res = yield handler.call( u'com.myapp.myproc2', options=types.CallOptions(on_progress=progress), ) self.assertEqual(42, res) # make sure we got *all* our progressive results for i in range(10): self.assertTrue(progressive[i].called) self.assertEqual(i, progressive[i].result)
def test_invoke_progressive_result_just_kwargs(self): handler = ApplicationSession() MockTransport(handler) @inlineCallbacks def bing(details=None): self.assertTrue(details is not None) self.assertTrue(details.progress is not None) details.progress(key='word') yield succeed(True) returnValue(42) got_progress = Deferred() def progress(key=None): got_progress.callback(key) # see MockTransport, must start with "com.myapp.myproc" yield handler.register( bing, u'com.myapp.myproc2', types.RegisterOptions(details_arg='details'), ) res = yield handler.call( u'com.myapp.myproc2', options=types.CallOptions(on_progress=progress), ) self.assertEqual(42, res) self.assertTrue(got_progress.called) self.assertEqual('word', got_progress.result)
def forward_procedure(self, func_path, uri, options=None): @inlineCallbacks def wrapped(*args, **kwargs): reply_channel_name = self.channel_layer.new_channel( '{}?'.format(uri)) payload = { 'func_path': func_path, 'uri': uri, 'args': args, 'kwargs': kwargs, 'reply_channel': reply_channel_name, } channel = Channel('wamp.events') channel.send(payload) d = Deferred() def cleanup(result): self.channels.remove(reply_channel_name) del self.reply_channels[reply_channel_name] self.log.info('result: {}'.format(result['total'])) d.addCallback(cleanup) self.channels.add(reply_channel_name) self.reply_channels[reply_channel_name] = d yield d self.log.info("registered procedure for '{}'".format(uri)) if options is None: options = types.RegisterOptions() return self.register(wrapped, uri, options=options)
def onJoin(self, details): log.msg("db:onJoin session attached {}".format(details)) if 'engine' in self.svar and 'topic_base' in self.svar: if self.svar['engine'] == 'PG9_4' or self.svar['engine'] == 'PG': from .db import postgres dbo = postgres.PG9_4(topic_base = self.svar['topic_base'], app_session = self, debug = self.svar['debug']) elif self.svar['engine'] == 'MYSQL14_14' or self.svar['engine'] == 'MYSQL': from .db import mysql dbo = mysql.MYSQL14_14(topic_base = self.svar['topic_base'], app_session = self, debug = self.svar['debug']) elif self.svar['engine'] == 'SQLITE3_3_8_2' or self.svar['engine'] == 'SQLITE3' or self.svar['engine'] == 'SQLITE': from .db import ausqlite3 dbo = ausqlite3.SQLITE3_3_8_2(topic_base = self.svar['topic_base'], app_session = self, debug = self.svar['debug']) else: raise Exception("Unsupported dbtype {} ".format(self.svar['engine'])) else: raise Exception("when instantiating this class DB you must provide engine=X and topic_base=Y") self.db = { 'instance': dbo } self.db['registration'] = {} r = types.RegisterOptions(details_arg = 'details') self.db['registration']['connect'] = yield self.register(dbo.connect, self.svar['topic_base']+'.connect', options = r) self.db['registration']['disconnect'] = yield self.register(dbo.disconnect, self.svar['topic_base']+'.disconnect', options = r) self.db['registration']['query'] = yield self.register(dbo.query, self.svar['topic_base']+'.query', options = r) self.db['registration']['operation'] = yield self.register(dbo.operation, self.svar['topic_base']+'.operation', options = r) self.db['registration']['watch'] = yield self.register(dbo.watch, self.svar['topic_base']+'.watch', options = r) self.db['registration']['info'] = yield self.register(dbo.info, self.svar['topic_base']+'.info', options = r) if 'dsn' in self.svar: log.msg("db:onJoin connecting... {}".format(self.svar['dsn'])) yield self.call(self.svar['topic_base'] + '.connect', self.svar['dsn']) log.msg("db:onJoin connecting established") log.msg("db bootstrap procedures registered")
def onJoin(self, details): print("Server ready {}".format(details)) try: yield from self.register(self, options=types.RegisterOptions( details_arg='details', discloseCaller=True)) print("procedure registered") except Exception as e: print("could not register procedure: {0}".format(e))
def test_concurrency_errors(crossbar): """ a returned error should reduce outstanding concurrency counter see: https://github.com/crossbario/crossbar/issues/1105 """ # what we do here is register one function with concurrency=2 that # will report errors on the first two invocations -- so our third # invocation should work fine. session = yield functest_session() def a_thing(*args, **kw): print("a thing {} {}".format(args, kw)) if len(a_thing.errors) and a_thing.errors.pop(): raise RuntimeError("a thing went wrong") a_thing.errors = [True, True] yield session.register( a_thing, u'foo.method', options=types.RegisterOptions(concurrency=2), ) errors = [] results = [] try: res0 = yield session.call(u'foo.method') results.append(res0) except Exception as e: errors.append(e) try: res1 = yield session.call(u'foo.method') results.append(res1) except Exception as e: errors.append(e) try: res2 = yield session.call(u'foo.method') results.append(res2) except Exception as e: errors.append(e) print("results: {}".format(results)) print(" errors: {}".format(errors)) assert len(errors) == 2 for err in errors: assert "a thing went wrong" in str(err) assert len(results) == 1 assert results == [None]
def test_invoke_progressive_result_error(self): handler = ApplicationSession() MockTransport(handler) @inlineCallbacks def bing(arg, details=None, key=None): self.assertTrue(details is not None) self.assertTrue(details.progress is not None) self.assertEqual(key, 'word') self.assertEqual('arg', arg) details.progress('life', something='nothing') yield succeed('meaning of') returnValue(42) got_progress = Deferred() progress_error = NameError('foo') logged_errors = [] def got_error(e, msg): logged_errors.append((e.value, msg)) handler.onUserError = got_error def progress(arg, something=None): self.assertEqual('nothing', something) got_progress.callback(arg) raise progress_error # see MockTransport, must start with "com.myapp.myproc" yield handler.register( bing, u'com.myapp.myproc2', types.RegisterOptions(details_arg='details'), ) res = yield handler.call( u'com.myapp.myproc2', 'arg', options=types.CallOptions(on_progress=progress), key='word', ) self.assertEqual(42, res) # our progress handler raised an error, but not before # recording success. self.assertTrue(got_progress.called) self.assertEqual('life', got_progress.result) # make sure our progress-handler error was logged self.assertEqual(1, len(logged_errors)) self.assertEqual(progress_error, logged_errors[0][0])
def onJoin(self, details): global _WampSession _WampSession = self ID = self.config.extra["ID"] print('WAMP session joined by :', ID) for name in ExposedCalls: regoption = types.RegisterOptions(u'exact', u'last') yield self.register(GetCallee(name), u'.'.join((ID, name)), regoption) for name in SubscribedEvents: yield self.subscribe(GetCallee(name), unicode(name)) for func in DoOnJoin: yield func(self)
def test_register(self): handler = ApplicationSession() MockTransport(handler) def on_call(*args, **kwargs): print("got call", args, kwargs) registration = yield handler.register(on_call, u'com.myapp.procedure1') self.assertTrue(type(registration.id) in (int, long)) registration = yield handler.register( on_call, u'com.myapp.procedure1', options=types.RegisterOptions(match=u'prefix')) self.assertTrue(type(registration.id) in (int, long))
async def _register_callees(self): for name, method, options in ScopeInspector.callees(self.scope): uri = self.scope.get_routing(method.registered).format(self.scope) options = types.RegisterOptions(**options) try: registered = await self.session.register( method, uri, options=options, ) self.callees.append(registered) self.session.log.debug("procedure `{uri}` registered", uri=uri) except Exception as e: self.session.log.error(uri) self.session.log.error( "could not register procedure `{uri}`: {e!r}", uri=uri, e=e) self.session.log.error(no_format(traceback.format_exc()))
def onJoin(self, details): global _WampSession _WampSession = self ID = self.config.extra["ID"] for name, kwargs in ExposedCalls: try: registerOptions = types.RegisterOptions(**kwargs) except TypeError as e: registerOptions = None print(_("TypeError register option: {}".format(e))) self.register(GetCallee(name), u'.'.join((ID, name)), registerOptions) for name in SubscribedEvents: self.subscribe(GetCallee(name), text(name)) for func in DoOnJoin: func(self) print(_('WAMP session joined (%s) by:' % time.ctime()), ID)
def onJoin(self, details): self.channel_layer = channel_layers["default"] Channel('wamp.join').send({'session': details.session}) while self.is_connected(): yield self.publish('com.example.bonjour', 2, options=types.PublishOptions(exclude_me=False)) self.call('com.example.hello', 'hey!') channel_name, result = self.channel_layer.receive_many( self.channels) if channel_name is None: yield sleep(SLEEP_TIME) continue elif channel_name == 'wamp.call': uri = result['uri'] args = result.get('args', []) kwargs = result.get('kwargs', {}) options = result.get('options', {}) if options: kwargs['options'] = types.CallOptions(**options) registration = self.call(uri, *args, **kwargs) elif channel_name == 'wamp.publish': topic = result['topic'] args = result.get('args', []) kwargs = result.get('kwargs', {}) options = result.get('options', {}) if options: kwargs['options'] = types.PublishOptions(**options) self.publish(topic, *args, **kwargs) elif channel_name == 'wamp.subscribe': func_path = result['func_path'] topic = result['topic'] options = result.get('options', {}) or {} subscribe_options = types.SubscribeOptions(**options) subscription = yield self.forward_subscriber( func_path, topic, subscribe_options) self.forward_subscription(result['reply_channel'], subscription) elif channel_name == 'wamp.unsubscribe': subscription_id = result['subscription_id'] subscription = self.subscriptions.pop(subscription_id) yield subscription.unsubscribe() elif channel_name == 'wamp.register': func_path = result['func_path'] uri = result['uri'] options = result.get('options', {}) or {} register_options = types.RegisterOptions(**options) registration = yield self.forward_procedure( func_path, uri, register_options) self.forward_registration(result['reply_channel'], registration) elif channel_name == 'wamp.unregister': registration_id = result['registration_id'] registration = self.subscriptions.pop(registration_id) yield registration.unregister() elif channel_name in self.reply_channels: self.reply_channels[channel_name].callback( *result['args'], **result['kwargs']) yield sleep(SLEEP_TIME) self.log.info('disconnected!') Channel('wamp.disconnect').send({ 'reason': 'not connected', }) self.disconnect() reactor.stop()