message: lock round access
diff: """XAIN FL Rounds"""
  +import threading
  from typing import Dict, List, Tuple
  from numpy import ndarray
  @@ -8,19 +9,21 @@ from xain_fl.tools.exceptions import DuplicatedUpdateError
  class Round:
  - """Class to manage the state of a single round.
  - This class contains the logic to handle all updates sent by the
  - participants during a round and does some sanity checks like preventing the
  - same participant to submit multiple updates during a single round.
  + """Class to manage the state of a single round. This class contains the logic to
  + handle all updates sent by the participants during a round in a thread-safe
  + manner and does some sanity checks like preventing the same participant from
  + submitting multiple updates within a single round.
  Args:
  participant_ids: The list of IDs of the participants selected
  to participate in this round.
  + updates: Dictionary of training updates indexed by participant ID.
  """
  def __init__(self, participant_ids: List[str]) -> None:
  self.participant_ids = participant_ids
  self.updates: Dict[str, Dict] = {}
  + self._lock: threading.Lock = threading.Lock()
  def add_selected(self, more_ids: List[str]) -> None:
  """Add to the collection of selected participants.
  @@ -29,6 +32,7 @@ class Round:
  more_ids: ids of participants to add.
  """
  + with self._lock:
  self.participant_ids.extend(more_ids)
  def remove_selected(self, participant_id: str) -> None:
  @@ -38,6 +42,7 @@ class Round:
  participant_id: id of participant to remove.
  """
  + with self._lock:
  try:
  self.participant_ids.remove(participant_id)
  except ValueError:
  @@ -59,11 +64,11 @@ class Round:
  DuplicatedUpdateError: If the participant already submitted his update this round.
  """
  + with self._lock:
  if participant_id in self.updates.keys():
  raise DuplicatedUpdateError(
  f"Participant {participant_id} already submitted the update for this round."
  )
  -
  self.updates[participant_id] = {
  "model_weights": model_weights,
  "aggregation_data": aggregation_data,
  @@ -78,6 +83,7 @@ class Round:
  round. `False` otherwise.
  """
  + with self._lock:
  return all(id in self.updates for id in self.participant_ids)
  def get_weight_updates(self) -> Tuple[List[ndarray], List[int]]:
  @@ -88,6 +94,7 @@ class Round:
  The lists of model weights and aggregation meta data from all participants.
  """
  + with self._lock:
  updates = [self.updates[id] for id in self.participant_ids]
  return (
  [upd["model_weights"] for upd in updates],
  