Ejemplo n.º 1
0
def add_to_vessel_status_monitor(monitorhandle, vesselhandle_list):
    """
  <Purpose>
    Adds the vesselhandles in vesselhandle_list to the specified monitor. If
    any already are watched by the monitor, they are silently ignored. There
    is no removal of previously added vesselhandles other than automatic
    removal done when vessels are unreachable or otherwise invalid.
    
    One intention of this function is that new vessels found via a
    lookup_node_locations_by_identity and then find_vessels_on_nodes can be
    passed to this function as a way of making sure the monitor knows about
    new vessels that a user has just obtained access to or which have recently
    come online. 
  <Arguments>
    monitorhandle
      A monitorhandle returned by register_vessel_status_monitor.
    vesselhandle_list
      A list of vesselhandles to add to the monitor.
  <Side Effects>
    The next run of the monitor will include the provided vesselhandles.
  <Exceptions>
    ValueError
      If no such monitorhandle exists (including if it was already removed).
  <Returns>
    None
  """
    experimentlib._validate_vesselhandle_list(vesselhandle_list)

    _monitor_lock.acquire()
    try:
        # Ensure the monitorhandle is valid.
        if not monitorhandle in _vessel_monitors:
            raise ValueError("The provided monitorhandle is invalid: " +
                             str(monitorhandle))

        for vesselhandle in vesselhandle_list:
            if vesselhandle not in _vessel_monitors[monitorhandle][
                    'vesselhandle_list']:
                _vessel_monitors[monitorhandle]['vesselhandle_list'].append(
                    vesselhandle)
                _vessel_monitors[monitorhandle]['vessels'][vesselhandle] = {}

    finally:
        _monitor_lock.release()
def add_to_vessel_status_monitor(monitorhandle, vesselhandle_list):
  """
  <Purpose>
    Adds the vesselhandles in vesselhandle_list to the specified monitor. If
    any already are watched by the monitor, they are silently ignored. There
    is no removal of previously added vesselhandles other than automatic
    removal done when vessels are unreachable or otherwise invalid.
    
    One intention of this function is that new vessels found via a
    lookup_node_locations_by_identity and then find_vessels_on_nodes can be
    passed to this function as a way of making sure the monitor knows about
    new vessels that a user has just obtained access to or which have recently
    come online. 
  <Arguments>
    monitorhandle
      A monitorhandle returned by register_vessel_status_monitor.
    vesselhandle_list
      A list of vesselhandles to add to the monitor.
  <Side Effects>
    The next run of the monitor will include the provided vesselhandles.
  <Exceptions>
    ValueError
      If no such monitorhandle exists (including if it was already removed).
  <Returns>
    None
  """
  experimentlib._validate_vesselhandle_list(vesselhandle_list)
  
  _monitor_lock.acquire()
  try:
    # Ensure the monitorhandle is valid.
    if not monitorhandle in _vessel_monitors:
      raise ValueError("The provided monitorhandle is invalid: " + str(monitorhandle))
    
    for vesselhandle in vesselhandle_list:
      if vesselhandle not in _vessel_monitors[monitorhandle]['vesselhandle_list']:
        _vessel_monitors[monitorhandle]['vesselhandle_list'].append(vesselhandle)
        _vessel_monitors[monitorhandle]['vessels'][vesselhandle] = {}
    
  finally:
    _monitor_lock.release()
def register_vessel_status_monitor(identity, vesselhandle_list, callback, waittime=300, concurrency=10):
  """
  <Purpose>
    Registers a vessel status monitor. Once registered, a monitor occassionally
    checks the status of each vessel. If the vessel's status has changed or was
    never checked before, the provided callback function is called with
    information about the status change.
  <Arguments>
    identity
      The identity to be used when looking checking vessel status. This is
      mostly needed to determine whether the vessel exists but no longer is
      usable by the identity (that is, if the public key of the identity is
      no longer neither the owner or a user of the vessel).
    vesselhandle_list
      A list of vesselhandles of the vessels to be monitored.
    callback
      The callback function. This should accept three arguments:
        (vesselhandle, oldstatus, newstatus)
      where oldstatus and newstatus are both strings. Any exceptions raised by
      the callback will be silently ignored, so the callback should implement
      exception handling.
    waittime
      How many seconds to wait between status checks. This will be the time
      between finishing a check of all vessels and starting another round of
      checking.
    concurrency
      The number of threads to use for communicating with nodes. This will be
      the maximum number of vessels that can be checked simultaneously.
  <Exceptions>
    None
  <Side Effects>
    Immediately starts a vessel monitor running.
  <Returns>
    A monitorhandle which can be used to update or cancel this monitor.
  """
  experimentlib._validate_vesselhandle_list(vesselhandle_list)
  experimentlib._validate_identity(identity)
  
  # We copy the vesselhandle_list so that the user doesn't directly modify.
  vesselhandle_list = vesselhandle_list[:]
  
  _monitor_lock.acquire()
  try:
    # Create a new monitor key in the the _vessel_monitors dict.
    for attempt in range(10):
      id = "MONITOR_" + str(random.random())
      if id not in _vessel_monitors:
        break
    else:
      # I don't intend users to need to worry about this exception. I also
      # don't know of a more specific built-in exception to use and I don't
      # feel this should raise a SeattleExperimentException. Therefore,
      # intentionally raising a generic Exception here.
      raise Exception("Can't generate a unique vessel monitor id. " + 
                      "This probably means a bug in experimentlib.py")
    _vessel_monitors[id] = {}
    
    _vessel_monitors[id]['vesselhandle_list'] = vesselhandle_list
    _vessel_monitors[id]['waittime'] = waittime
    _vessel_monitors[id]['callback'] = callback
    _vessel_monitors[id]['concurrency'] = concurrency
    _vessel_monitors[id]['identity'] = identity
    # Whether the monitor was canceled/removed. Used to indicate to a running
    # monitor that it should stop doing work.
    _vessel_monitors[id]['canceled'] = False
    
    # Keeps track of the status of individual vessels. This is used by
    # vessel monitors to determine when the status has changed.
    _vessel_monitors[id]['vessels'] = {}
    for handle in vesselhandle_list:
      _vessel_monitors[id]['vessels'][handle] = {}
    
    # The first time we run it we don't delay. Storing the timer handle is a
    # bit useless in this case but we do it for consistency.
    _vessel_monitors[id]['timerhandle'] = settimer(0, _run_monitor, [_vessel_monitors[id]])
    
    return id
  
  finally:
    _monitor_lock.release()
Ejemplo n.º 4
0
def register_vessel_status_monitor(identity,
                                   vesselhandle_list,
                                   callback,
                                   waittime=300,
                                   concurrency=10):
    """
  <Purpose>
    Registers a vessel status monitor. Once registered, a monitor occassionally
    checks the status of each vessel. If the vessel's status has changed or was
    never checked before, the provided callback function is called with
    information about the status change.
  <Arguments>
    identity
      The identity to be used when looking checking vessel status. This is
      mostly needed to determine whether the vessel exists but no longer is
      usable by the identity (that is, if the public key of the identity is
      no longer neither the owner or a user of the vessel).
    vesselhandle_list
      A list of vesselhandles of the vessels to be monitored.
    callback
      The callback function. This should accept three arguments:
        (vesselhandle, oldstatus, newstatus)
      where oldstatus and newstatus are both strings. Any exceptions raised by
      the callback will be silently ignored, so the callback should implement
      exception handling.
    waittime
      How many seconds to wait between status checks. This will be the time
      between finishing a check of all vessels and starting another round of
      checking.
    concurrency
      The number of threads to use for communicating with nodes. This will be
      the maximum number of vessels that can be checked simultaneously.
  <Exceptions>
    None
  <Side Effects>
    Immediately starts a vessel monitor running.
  <Returns>
    A monitorhandle which can be used to update or cancel this monitor.
  """
    experimentlib._validate_vesselhandle_list(vesselhandle_list)
    experimentlib._validate_identity(identity)

    # We copy the vesselhandle_list so that the user doesn't directly modify.
    vesselhandle_list = vesselhandle_list[:]

    _monitor_lock.acquire()
    try:
        # Create a new monitor key in the the _vessel_monitors dict.
        for attempt in range(10):
            id = "MONITOR_" + str(random.random())
            if id not in _vessel_monitors:
                break
        else:
            # I don't intend users to need to worry about this exception. I also
            # don't know of a more specific built-in exception to use and I don't
            # feel this should raise a SeattleExperimentException. Therefore,
            # intentionally raising a generic Exception here.
            raise Exception("Can't generate a unique vessel monitor id. " +
                            "This probably means a bug in experimentlib.py")
        _vessel_monitors[id] = {}

        _vessel_monitors[id]['vesselhandle_list'] = vesselhandle_list
        _vessel_monitors[id]['waittime'] = waittime
        _vessel_monitors[id]['callback'] = callback
        _vessel_monitors[id]['concurrency'] = concurrency
        _vessel_monitors[id]['identity'] = identity
        # Whether the monitor was canceled/removed. Used to indicate to a running
        # monitor that it should stop doing work.
        _vessel_monitors[id]['canceled'] = False

        # Keeps track of the status of individual vessels. This is used by
        # vessel monitors to determine when the status has changed.
        _vessel_monitors[id]['vessels'] = {}
        for handle in vesselhandle_list:
            _vessel_monitors[id]['vessels'][handle] = {}

        # The first time we run it we don't delay. Storing the timer handle is a
        # bit useless in this case but we do it for consistency.
        _vessel_monitors[id]['timerhandle'] = settimer(0, _run_monitor,
                                                       [_vessel_monitors[id]])

        return id

    finally:
        _monitor_lock.release()