Exemplo n.º 1
0
 def __init__(self, cache_size=config_cdash.CACHE_LIMIT):
     """ Initialize the Cache manager. 
         Start the Priority Cache with max_size = cache_size
     """
     self.fetch_requests = 0
     self.prefetch_request_count = 0
     config_cdash.LOG.info('Initializing the Cache Manager')
     self.cache = PriorityCache(cache_size)
     self.prefetch_queue = CheckableQueue()
     self.current_queue = CheckableQueue()
     self.stop = threading.Event()
     self.current_thread = threading.Thread(target=self.current_function, args=())
     self.current_thread.daemon = True
     self.current_thread.start()
     config_cdash.LOG.info('Started the Current fetch thread')
     self.prefetch_thread = threading.Thread(target=self.prefetch_function, args=())
     self.prefetch_thread.daemon = True
     self.prefetch_thread.start()
     config_cdash.LOG.info('Started the Preftech thread')
Exemplo n.º 2
0
class CacheManager():
    def __init__(self, cache_size=config_cdash.CACHE_LIMIT):
        """ Initialize the Cache manager. 
            Start the Priority Cache with max_size = cache_size
        """
        self.fetch_requests = 0
        self.prefetch_request_count = 0
        config_cdash.LOG.info('Initializing the Cache Manager')
        self.cache = PriorityCache(cache_size)
        self.prefetch_queue = CheckableQueue()
        self.current_queue = CheckableQueue()
        self.stop = threading.Event()
        self.current_thread = threading.Thread(target=self.current_function, args=())
        self.current_thread.daemon = True
        self.current_thread.start()
        config_cdash.LOG.info('Started the Current fetch thread')
        self.prefetch_thread = threading.Thread(target=self.prefetch_function, args=())
        self.prefetch_thread.daemon = True
        self.prefetch_thread.start()
        config_cdash.LOG.info('Started the Preftech thread')

    def terminate(self):
        self.stop.set()
        self.prefetch_thread.join()
        self.current_thread.join()

    def fetch_file(self, file_path, username=None,session_id=None):
        """ Module to get the file """
        config_cdash.LOG.info('Fetching the file {}'.format(file_path))
        # Add the current request to the current_thread
        # This is to ensure that the pre-fetch process does not hold the
        while file_path in self.prefetch_queue:
            config_cdash.LOG.warning('Witing untill Prefetch is complete')
            time.sleep(2)
            continue
        local_filepath, http_headers = self.cache.get_file(file_path, config_cdash.FETCH_CODE)
        config_cdash.LOG.info('Added {} to current queue'.format(file_path))
        self.current_queue.put((file_path, username, session_id))
        self.fetch_requests += 1
        config_cdash.LOG.info('Total fetch Requests = {}'.format(self.fetch_requests))
        return local_filepath, http_headers

    def current_function(self):
        """
        Thread reads the current requests and generates the prefetch requests
        that determines the next segment for all the current fetched bitrates.

        We use a separate prefetch queue to ensure that the prefetch does not affect the performance
        of the current requests
        """
        config_cdash.LOG.info('Current Thread: Started thread. Stop value = {}'.format(self.stop.is_set()))
        while not self.stop.is_set():
            try:
                current_request, username, session_id = self.current_queue.get(timeout=None)
                config_cdash.LOG.info('Retrieved the file: {}'.format(current_request))
            except Queue.Empty:
                config_cdash.LOG.error('Current Thread: Thread GET returned Empty value')
                current_request = None
                continue
            # Determining the next bitrates and adding to the prefetch list
            if current_request:
                if config_cdash.PREFETCH_SCHEME == 'SMART':
                    throughput = get_throughput_info(username, session_id, config_cdash.LIMIT, config_cdash.SCHEME)
                    config_cdash.LOG.info('average of throughput: = {}'.format(throughput))
                    prefetch_request, prefetch_bitrate = get_prefetch(current_request, config_cdash.PREFETCH_SCHEME, throughput)
                else:
                    prefetch_request, prefetch_bitrate = get_prefetch(current_request, config_cdash.PREFETCH_SCHEME, None)
            if not segment_exists(prefetch_request):
                config_cdash.LOG.info('Segment not there {}'.format(prefetch_request))
                if check_content_server(prefetch_request):
                    config_cdash.LOG.info('Current Thread: Current segment: {}, Next segment: {}'.format(current_request,
                                                                                                  prefetch_request))
                    self.prefetch_queue.put(prefetch_request)
                    config_cdash.LOG.info('Pre-fetch queue count = {}'.format(self.prefetch_queue.qsize()))
                else:
                    config_cdash.LOG.info('Current Thread: Invalid Next segment: {}'.format(current_request, prefetch_request))
            else:
                config_cdash.LOG.info('Segment already there {}'.format(prefetch_request))
        else:
            config_cdash.LOG.warning('Current Thread: terminated')

    def prefetch_function(self):
        """ Function that reads the contents of the prefetch table in the database and pre-fetches the file into
            the cache
            We use a separate prefetch queue to ensure that the prefetch does not affect the performance
            of the current requests
        """
        while not self.stop.is_set():
            try:
                # Pre-fetching the files
                prefetch_request = self.prefetch_queue.get(timeout=None)
            except Queue.Empty:
                config_cdash.LOG.error('Could not read from the Pre-fetch queue')
                time.sleep(config_cdash.WAIT_TIME)
                continue
            config_cdash.LOG.info('Pre-fetching the segment: {}'.format(prefetch_request))
            self.cache.get_file(prefetch_request, config_cdash.PREFETCH_CODE)
            self.prefetch_request_count += 1
            config_cdash.LOG.info('Pre-fetch request count = {}'.format(self.prefetch_request_count))
        else:
            config_cdash.LOG.warning('Pre-fetch thread terminated')
Exemplo n.º 3
0
class CacheManager():
    def __init__(self, cache_size=config_cdash.CACHE_LIMIT):
        """ Initialize the Cache manager. 
            Start the Priority Cache with max_size = cache_size
        """
        self.fetch_requests = 0
        self.prefetch_request_count = 0
        config_cdash.LOG.info('Initializing the Cache Manager')
        self.cache = PriorityCache(cache_size)
        self.prefetch_queue = CheckableQueue()
        self.backup_prefetch_queue = CheckableQueue()
        self.current_queue = CheckableQueue()
        self.stop = threading.Event()
        self.current_thread = threading.Thread(target=self.current_function, args=())
        self.current_thread.daemon = True
        self.current_thread.start()
        config_cdash.LOG.info('Started the Current fetch thread')
        self.prefetch_thread = threading.Thread(target=self.prefetch_function, args=())
        self.prefetch_thread.daemon = True
        self.prefetch_thread.start()
        config_cdash.LOG.info('Started the Preftech thread')
        self.list_data=[]

    def terminate(self):
        self.stop.set()
        self.prefetch_thread.join()
        self.current_thread.join()

    def fetch_file(self, file_path, username=None,session_id=None):
        """ Module to get the file """
        config_cdash.LOG.info('Fetching the file {}'.format(file_path))
        n=self.backup_prefetch_queue.qsize()
        config_cdash.LOG.info('size of backup_prefetch_queue {} '.format(n))
        if n!=0:
            #item = self.backup_prefetch_queue.get()
            #config_cdash.LOG.info('item {}'.format(item))
            #config_cdash.LOG.info('size of backup_prefetch_queue {} '.format(n))
            while file_path in self.backup_prefetch_queue.queue and not segment_exists(file_path):
                config_cdash.LOG.warning('Witing untill Prefetch is complete')
                time.sleep(1)
                continue
            if file_path not in self.backup_prefetch_queue.queue and not segment_exists(file_path):
                config_cdash.LOG.warning('the request is not prefetched yet and not in the cache')

        local_filepath, http_headers = self.cache.get_file(file_path, config_cdash.FETCH_CODE)
        config_cdash.LOG.info('Added {} to current queue'.format(file_path))
        #self.current_queue.put((file_path, username, session_id))
        self.fetch_requests += 1
        config_cdash.LOG.info('Total fetch Requests = {}'.format(self.fetch_requests))
        return local_filepath, http_headers

    def current_function(self):
        """
        Thread reads the current requests and generates the prefetch requests
        that determines the next segment for all the current fetched bitrates.

        We use a separate prefetch queue to ensure that the prefetch does not affect the performance
        of the current requests
        """
        config_cdash.LOG.info('Current Thread: Started thread. Stop value = {}'.format(self.stop.is_set()))
        while not self.stop.is_set():
            try:
                current_request, username, session_id = self.current_queue.get(timeout=None)
                config_cdash.LOG.info('Retrieved the file: {}'.format(current_request))
            except Queue.Empty:
                config_cdash.LOG.error('Current Thread: Thread GET returned Empty value')
                current_request = None
                continue
            # Determining the next bitrates and adding to the prefetch list
            if current_request:
                if config_cdash.PREFETCH_SCHEME == 'SMART':
                    a=0.8
                    d=0.2
                    config_cdash.LOG.info('smart')
                    throughput_client= self.get_throughput_client(username, session_id)
                    if throughput_client== None:
                        config_cdash.LOG.info('throughput client:=None')
                        throughput= self.get_throughput_info(username, session_id, config_cdash.LIMIT, config_cdash.SCHEME)
                        config_cdash.LOG.info('average of throughput: = {}'.format(throughput))
                        forecast_throughput=throughput
                        self.insert_forecast(username, session_id,0.0)
                        self.insert_trend(username, session_id,0.0)
                        config_cdash.LOG.info('forecast throughput equal throughput:= {}'.format(forecast_throughput))
                        prefetch_request, prefetch_bitrate = get_prefetch(current_request, config_cdash.PREFETCH_SCHEME,forecast_throughput)
                    else:
                        config_cdash.LOG.info('throughput client:= {}'.format(throughput_client))
                        At_1=float(throughput_client)
                        config_cdash.LOG.info('type of At_1:= {}'.format(type(At_1)))
                        FIT_t_1=self.get_previous_forecast(username, session_id)
                        config_cdash.LOG.info('previous forecast:= {}'.format(FIT_t_1))
                        config_cdash.LOG.info('type of FIT_t_1:= {}'.format(type(FIT_t_1)))
                        Tt_1=self.get_previous_trend(username, session_id)
                        config_cdash.LOG.info('previous trend:= {}'.format(Tt_1))
                        config_cdash.LOG.info('type of Tt_1:= {}'.format(type(Tt_1)))
                        Ft=FIT_t_1+a*(At_1-FIT_t_1)
                        Tt=Tt_1+d*(Ft-FIT_t_1)
                        FIT_t=Ft+Tt
                        self.insert_forecast(username, session_id,FIT_t)
                        self.insert_trend(username, session_id,Tt)
                        config_cdash.LOG.info('forecast throughput: {}'.format(FIT_t))
                        prefetch_request, prefetch_bitrate = get_prefetch(current_request, config_cdash.PREFETCH_SCHEME,FIT_t)
                else:
                    prefetch_request, prefetch_bitrate = get_prefetch(current_request, config_cdash.PREFETCH_SCHEME, None)
                    config_cdash.LOG.info('not smart')
            if not segment_exists(prefetch_request):
                config_cdash.LOG.info('Segment not there {}'.format(prefetch_request))
                if check_content_server(prefetch_request):
                    t=type(prefetch_request)
                    config_cdash.LOG.info('Type will be saved in queue: {}'.format(t))
                    config_cdash.LOG.info('Current Thread: Current segment: {}, Next segment: {}'.format(current_request,
                                                                                                  prefetch_request))
                    self.prefetch_queue.put(prefetch_request)
                    self.backup_prefetch_queue.put(prefetch_request)
                    config_cdash.LOG.info('Pre-fetch queue count = {}'.format(self.prefetch_queue.qsize()))
                else:
                    config_cdash.LOG.info('Current Thread: Invalid Next segment: {}'.format(current_request, prefetch_request))
            else:
                config_cdash.LOG.info('Segment already there {}'.format(prefetch_request))
        else:
            config_cdash.LOG.warning('Current Thread: terminated')

    def prefetch_function(self):
        """ Function that reads the contents of the prefetch table in the database and pre-fetches the file into
            the cache
            We use a separate prefetch queue to ensure that the prefetch does not affect the performance
            of the current requests
        """
        while not self.stop.is_set():
            try:
                # Pre-fetching the files
                prefetch_request = self.prefetch_queue.get(timeout=None)
            except Queue.Empty:
                config_cdash.LOG.error('Could not read from the Pre-fetch queue')
                time.sleep(config_cdash.WAIT_TIME)
                continue
            #config_cdash.LOG.info('user {} Pre-fetching the segment: {}'.format(username,prefetch_request))
            config_cdash.LOG.info('Pre-fetching the segment: {}'.format(prefetch_request))
            self.cache.get_file(prefetch_request, config_cdash.PREFETCH_CODE)
            self.prefetch_request_count += 1
            config_cdash.LOG.info('Pre-fetch request count = {}'.format(self.prefetch_request_count))
        else:
            config_cdash.LOG.warning('Pre-fetch thread terminated')


    def get_throughput_info(self,username, session_id, limit, scheme='average'):
        last_row_tuple=self.list_data[-1]
        config_cdash.LOG.info('last row = {}'.format(last_row_tuple))
        cache_throughput=last_row_tuple[5]
        return cache_throughput


    def get_throughput_client(self,username, session_id):
        last_row_tuple=self.list_data[-1]
        config_cdash.LOG.info('last row = {}'.format(last_row_tuple))
        client_throughput=last_row_tuple[6]
        return client_throughput

    def insert_forecast(self,username, session_id,forecast):
        last_row_tuple=self.list_data[-1]
        config_cdash.LOG.info('last row = {}'.format(last_row_tuple))
        last_row=list(last_row_tuple)
        last_row[8]=forecast
        last_row_tuple=tuple(last_row)
        config_cdash.LOG.info('last row = {}'.format(last_row_tuple))
        self.list_data[-1]=last_row_tuple
        #config_cdash.LOG.info('list_data= {}'.format(self.list_data))

    def get_previous_forecast(self,username, session_id):
        previous_row_tuple=self.list_data[-2]
        config_cdash.LOG.info('previos row = {}'.format(previous_row_tuple))
        forecast=previous_row_tuple[8]
        return forecast

    def insert_trend(self,username, session_id,trend):
        last_row_tuple=self.list_data[-1]
        config_cdash.LOG.info('last row = {}'.format(last_row_tuple))
        last_row=list(last_row_tuple)
        last_row[7]=trend
        last_row_tuple=tuple(last_row)
        config_cdash.LOG.info('last row = {}'.format(last_row_tuple))
        self.list_data[-1]=last_row_tuple
        #config_cdash.LOG.info('list_data= {}'.format(self.list_data))

    def get_previous_trend(self,username, session_id):
        previous_row_tuple=self.list_data[-2]
        config_cdash.LOG.info('previous row = {}'.format(previous_row_tuple))
        trend=previous_row_tuple[7]
        return trend