3
3
4
4
# Contest Management System - http://cms-dev.github.io/
5
5
# Copyright © 2010-2014 Giovanni Mascellani <[email protected] >
6
- # Copyright © 2010-2013 Stefano Maggiolo <[email protected] >
6
+ # Copyright © 2010-2014 Stefano Maggiolo <[email protected] >
7
7
# Copyright © 2010-2012 Matteo Boscariol <[email protected] >
8
8
# Copyright © 2013 Luca Wehrstedt <[email protected] >
9
9
#
37
37
import signal
38
38
import socket
39
39
import _socket
40
- import sys
41
40
import time
42
41
43
42
import gevent
46
45
from gevent .server import StreamServer
47
46
from gevent .backdoor import BackdoorServer
48
47
49
- from cms import config , mkdir , ServiceCoord , Address , get_service_address
48
+ from cms import ConfigError , config , mkdir , ServiceCoord , Address , \
49
+ get_service_address
50
50
from cms .log import root_logger , shell_handler , ServiceFilter , \
51
51
CustomFormatter , LogServiceHandler , FileHandler
52
52
from cmscommon .datetime import monotonic_time
53
53
54
- from .rpc import rpc_method , RemoteServiceServer , RemoteServiceClient
54
+ from .rpc import rpc_method , RemoteServiceServer , RemoteServiceClient , \
55
+ FakeRemoteServiceClient
55
56
56
57
57
58
logger = logging .getLogger (__name__ )
@@ -99,9 +100,9 @@ def __init__(self, shard=0):
99
100
try :
100
101
address = get_service_address (self ._my_coord )
101
102
except KeyError :
102
- logger . critical ( "Couldn't find %r in the configuration." ,
103
- self . _my_coord )
104
- sys . exit ( 1 )
103
+ raise ConfigError ( "Unable to find address for service %r. "
104
+ "Is it specified in core_services in cms.conf?" %
105
+ ( self . _my_coord ,) )
105
106
106
107
self .rpc_server = StreamServer (address , self ._connection_handler )
107
108
self .backdoor = None
@@ -172,7 +173,8 @@ def _connection_handler(self, sock, address):
172
173
remote_service = RemoteServiceServer (self , address )
173
174
remote_service .handle (sock )
174
175
175
- def connect_to (self , coord , on_connect = None , on_disconnect = None ):
176
+ def connect_to (self , coord , on_connect = None , on_disconnect = None ,
177
+ must_be_present = True ):
176
178
"""Return a proxy to a remote service.
177
179
178
180
Obtain a communication channel to the remote service at the
@@ -184,12 +186,26 @@ def connect_to(self, coord, on_connect=None, on_disconnect=None):
184
186
connects.
185
187
on_disconnect (function|None): to be called when it
186
188
disconnects.
189
+ must_be_present (bool): if True, the coord must be present in
190
+ the configuration; otherwise, it can be missing and in
191
+ that case the return value is a fake client (that is, a
192
+ client that never connects and ignores all calls).
187
193
188
194
return (RemoteServiceClient): a proxy to that service.
189
195
190
196
"""
191
197
if coord not in self .remote_services :
192
- service = RemoteServiceClient (coord , auto_retry = 0.5 )
198
+ try :
199
+ service = RemoteServiceClient (coord , auto_retry = 0.5 )
200
+ except KeyError :
201
+ # The coordinates are invalid: raise a ConfigError if
202
+ # the service was needed, or return a dummy client if
203
+ # the service was optional.
204
+ if must_be_present :
205
+ raise ConfigError ("Missing address and port for %s "
206
+ "in cms.conf." % (coord , ))
207
+ else :
208
+ service = FakeRemoteServiceClient (coord , None )
193
209
service .connect ()
194
210
self .remote_services [coord ] = service
195
211
else :
0 commit comments