def _update(self): logger.info('updating...') self._last_update = datetime.datetime.now(TZ) # create working copy for thread safety stations = copy.deepcopy(self._stations) # clear old times for id in stations: stations[id].clear_train_data() routes = defaultdict(set) for i, feed_url in enumerate(self._FEED_URLS): mta_data = self._load_mta_feed(feed_url) if not mta_data: continue max_time = self._last_update + datetime.timedelta(minutes = self._MAX_MINUTES) for entity in mta_data.entity: trip = Trip(entity) if not trip.is_valid(): continue direction = trip.direction[0] route_id = trip.route_id for update in entity.trip_update.stop_time_update: trip_stop = TripStop(update) if trip_stop.time < self._last_update or trip_stop.time > max_time: continue stop_id = trip_stop.stop_id if stop_id not in self._stops_to_stations: logger.info('Stop %s not found', stop_id) continue station_id = self._stops_to_stations[stop_id] stations[station_id].add_train(route_id, direction, trip_stop.time, mta_data.timestamp) routes[route_id].add(stop_id) # sort by time for id in stations: stations[id].sort_trains(self._MAX_TRAINS) with self._read_lock: self._routes = routes self._stations = stations
def _update(self): if not self._update_lock.acquire(False): logger.info('Update locked!') lock_age = datetime.datetime.now() - self._update_lock_time if lock_age.total_seconds() > self._LOCK_TIMEOUT: self._update_lock = threading.Lock() logger.info('Cleared expired update lock') return self._update_lock_time = datetime.datetime.now() logger.info('updating...') # create working copy for thread safety stations = copy.deepcopy(self._stations) # clear old times for id in stations: stations[id]['N'] = [] stations[id]['S'] = [] stations[id]['routes'] = set() stops = self._build_stops_index(stations) routes = defaultdict(set) for i, feed_url in enumerate(self._FEED_URLS): mta_data = self._load_mta_feed(feed_url) if not mta_data: continue self._last_update = mta_data.timestamp self._MAX_TIME = self._last_update + datetime.timedelta( minutes=self._MAX_MINUTES) for entity in mta_data.entity: trip = Trip(entity) if not trip.is_valid(): continue direction = trip.direction[0] route_id = trip.route_id for update in entity.trip_update.stop_time_update: trip_stop = TripStop(update) time = trip_stop.time if time < self._last_update or time > self._MAX_TIME: continue stop_id = trip_stop.stop_id if stop_id not in stops: logger.info('Stop %s not found', stop_id) continue station = stops[stop_id] station['routes'].add(route_id) station[direction].append({ 'route': route_id, 'time': time }) routes[route_id].add(stop_id) # sort by time for id in stations: if stations[id]['S'] or stations[id]['N']: stations[id]['hasData'] = True stations[id]['S'] = sorted( stations[id]['S'], key=itemgetter('time'))[:self._MAX_TRAINS] stations[id]['N'] = sorted( stations[id]['N'], key=itemgetter('time'))[:self._MAX_TRAINS] else: stations[id]['hasData'] = False with self._read_lock: self._stops = stops self._routes = routes self._stations = stations self._update_lock.release()