Repository: scaleoutsystems/fedn
Issue: Sometimes after a client restart/reconnect, it takes a long time before it takes part in training rounds 

**Severity**
- [ ] Critical/Blocker (select if the issue makes the application unusable or causes serious data loss)
- [ ] High (select if the issue affects a major feature and there is no workaround or the available workaround is very complex)
- [x] Medium (select if the issue affects a minor feature or affects a major feature but has an easy enough workaround to not cause any major inconvenience)
- [ ] Low (select if the issue doesn't significantly affect the user experience, like minor visual bugs)

**Describe the bug**
It happens that, after a client disconnect and reconnect, it takes a while before the client starts participating in training, even though it is registered quickly to the combiner and gets reported as active/available. 

**Reproduction Steps**
1.  Start client.
2. Train a round.  
3. Stop and start client. 
4. Start a round. 
5.  Sometimes  the client does not start training. 

It is not deterministically reproducible. 
 
**Expected behavior**
If it is shown as connected and available, it should partake in the training. 



Changed files:
fedn/fedn/client.py, fedn/fedn/combiner.py

diff --git a/fedn/fedn/client.py b/fedn/fedn/client.py
index eaf4815..d4c42d7 100644
--- a/fedn/fedn/client.py
+++ b/fedn/fedn/client.py
@@ -271,7 +271,6 @@ class Client:
         r.sender.name = self.name
         r.sender.role = fedn.WORKER
         metadata = [('client', r.sender.name)]
-        import time
         while True:
             try:
                 for request in self.orchestrator.ModelUpdateRequestStream(r, metadata=metadata):
@@ -287,8 +286,9 @@ class Client:
                 timeout = 5
                 print("CLIENT __listen_to_model_update_request_stream: GRPC ERROR {} retrying in {}..".format(
                     status_code.name, timeout), flush=True)
-                import time
                 time.sleep(timeout)
+            except:
+                raise
 
     def _listen_to_model_validation_request_stream(self):
         """Subscribe to the model validation request stream. """
@@ -315,7 +315,6 @@ class Client:
 
     def process_request(self):
         """Process training and validation tasks. """
-
         while True:
             (task_type, request) = self.inbox.get()
             if task_type == 'train':
@@ -378,8 +377,6 @@ class Client:
                 self.state = ClientState.idle
                 self.inbox.task_done()
 
-
-
     def _process_training_request(self, model_id):
         """Process a training (model update) request. 
         
diff --git a/fedn/fedn/combiner.py b/fedn/fedn/combiner.py
index 51683f5..0e60400 100644
--- a/fedn/fedn/combiner.py
+++ b/fedn/fedn/combiner.py
@@ -52,6 +52,8 @@ class Combiner(rpc.CombinerServicer, rpc.ReducerServicer, rpc.ConnectorServicer,
     """ Communication relayer. """
 
     def __init__(self, connect_config):
+
+        # Holds client queues 
         self.clients = {}
 
         self.modelservice = ModelService()
@@ -505,8 +507,11 @@ class Combiner(rpc.CombinerServicer, rpc.ReducerServicer, rpc.ConnectorServicer,
 
         self._send_status(status)
 
-        while True:
-            yield q.get()
+        while context.is_active():
+            try:
+                yield q.get(timeout=1.0)
+            except queue.Empty:
+                pass 
 
     def ModelUpdateRequestStream(self, response, context):
         """ A server stream RPC endpoint. Messages from client stream. """
@@ -528,8 +533,12 @@ class Combiner(rpc.CombinerServicer, rpc.ReducerServicer, rpc.ConnectorServicer,
 
         self._send_status(status)
 
-        while True:
-            yield q.get()
+        while context.is_active():
+            try:
+                yield q.get(timeout=1.0)
+            except queue.Empty:
+                pass 
+           
 
     def ModelValidationStream(self, update, context):
         """
@@ -549,8 +558,11 @@ class Combiner(rpc.CombinerServicer, rpc.ReducerServicer, rpc.ConnectorServicer,
 
         self._send_status(status)
 
-        while True:
-            yield q.get()
+        while context.is_active():
+            try:
+                yield q.get(timeout=1.0)
+            except queue.Empty:
+                pass 
 
     def ModelValidationRequestStream(self, response, context):
         """ A server stream RPC endpoint. Messages from client stream. """
@@ -568,8 +580,11 @@ class Combiner(rpc.CombinerServicer, rpc.ReducerServicer, rpc.ConnectorServicer,
 
         self._send_status(status)
 
-        while True:
-            yield q.get()
+        while context.is_active():
+            try:
+                yield q.get(timeout=1.0)
+            except queue.Empty:
+                pass 
 
     def SendModelUpdateRequest(self, request, context):
         """ Send a model update request. """