00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 __facility__ = "Online"
00011 __abstract__ = "GLAST LAT data distribution polling class"
00012 __author__ = "R. Claus <Claus@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__ = "2005/07/23 00:08:27"
00014 __updated__ = "$Date: 2005/09/22 00:29:31 $"
00015 __version__ = "$Revision: 1.5 $"
00016 __release__ = "$Name: HEAD $"
00017 __credits__ = "SLAC"
00018
00019 import LICOS.copyright_SLAC
00020
00021
00022 import DataDistributor as DD
00023 import threading
00024 import copy
00025 import time
00026
00027
00028 class DataDistributorPoll(DD.DataDistributorClient):
00029 """!\brief Data distributor client that polls for samples of data.
00030
00031 Use of this class involves the starting of a thread that constantly receives
00032 the data arriving in the base class's socket. Keeping the socket drained of
00033 data allows the user of this class to get the most recent data received, thus
00034 avoiding getting data with a bursty time structure. Whenever the application
00035 calls the receive() method, it gets the most recent data sample. Because of
00036 the reference counting method used by Python objects, no copy of the data
00037 needs to be made to avoid the data changing from underneath the application.
00038 The application can hold onto the data reference as long as it likes.
00039 Whenever new data appears a new reference is created, and is possibly deleted
00040 before the application gets access to it, leaving any existing reference
00041 alone. When the application tries to get access to the latest data, it gets
00042 a copy of the most recent reference, and the previous reference is deleted,
00043 if it has gone out of scope.
00044 """
00045 def __init__(self, name, length = 64*1024):
00046 """!\brief DataDistributorPoll constructor.
00047
00048 \param name The name of the type of data that the client wants to receive.
00049 See the DataDistributorAddress class.
00050 \param length The size in bytes of the buffer to allocate for receiving the
00051 data. Defaults to 64 KB.
00052 """
00053 DD.DataDistributorClient.__init__(self, name, length)
00054 self.__pollTaskQuit = False
00055 self.__pollTask = None
00056 self.__data = None
00057 self.__dataCopy = None
00058 self.__sender = None
00059
00060 def start(self):
00061 """!\brief Start the polling thread.
00062
00063 """
00064 self.__pollTask = threading.Thread(None, self.__poll, 'DataDistributorPoll')
00065 if self.__pollTask is not None:
00066 self.__pollTask.start()
00067
00068 def stop(self):
00069 """!\brief Stop the polling thread.
00070
00071 """
00072 self.returnNone()
00073 self.__pollTaskQuit = True
00074 self.__pollTask.join()
00075
00076 def __poll(self):
00077 """!\brief Internal routine to drain the data distributor client socket.
00078
00079 """
00080 while not self.__pollTaskQuit:
00081 self.__data, self.__sender = DD.DataDistributorClient.receive(self)
00082 time.sleep(.001)
00083
00084 def receive(self):
00085 """!\brief Receive a sampled value of the data and sender information.
00086
00087 \return A list of the sampled data and sender's identification string.
00088 If the data buffer has not been refreshed since the last call,
00089 return None, None.
00090 """
00091
00092
00093
00094 if self.__data is not self.__dataCopy:
00095 self.__dataCopy = self.__data
00096 return self.__dataCopy, self.__sender
00097 else:
00098 return None, None