def end_auction(self): request_id = generate_request_id() LOGGER.info('---------------- End auction ----------------', extra={ "JOURNAL_REQUEST_ID": request_id, "MESSAGE_ID": AUCTION_WORKER_SERVICE_END_AUCTION }) LOGGER.debug("Stop server", extra={"JOURNAL_REQUEST_ID": request_id}) if self.context.get('server'): self.context['server'].stop() delete_mapping(self.context['worker_defaults'], self.context['auction_doc_id']) LOGGER.debug("Clear mapping", extra={"JOURNAL_REQUEST_ID": request_id}) stage = { 'start': datetime.now(TIMEZONE).isoformat(), 'type': PREANNOUNCEMENT, } with update_auction_document(self.context, self.database) as auction_document: auction_document["stages"].append(stage) auction_document["current_stage"] = len( auction_document["stages"]) - 1 auction_protocol = approve_auction_protocol_info_on_announcement( self.context['auction_document'], self.context['auction_protocol']) self.context['auction_protocol'] = auction_protocol LOGGER.info('Audit data: \n {}'.format( yaml_dump(self.context['auction_protocol'])), extra={"JOURNAL_REQUEST_ID": request_id}) LOGGER.info(self.context['auction_protocol']) result = self.datasource.update_source_object( self.context['auction_data'], self.context['auction_document'], self.context['auction_protocol']) if result and isinstance(result, dict): self.context['auction_document'] = result auction_end = datetime.now(TIMEZONE) stage = prepare_end_stage(auction_end) with update_auction_document(self.context, self.database) as auction_document: auction_document["stages"].append(stage) auction_document["current_stage"] = len( auction_document["stages"]) - 1 auction_document['endDate'] = auction_end.isoformat() self.context['end_auction_event'].set()
def cancel_auction(self): self.context['auction_document'] = self.database.get_auction_document( self.context['auction_doc_id']) if self.context['auction_document']: with utils.update_auction_document( self.context, self.database) as auction_document: LOGGER.info("Auction {} canceled".format( self.context['auction_doc_id']), extra={ 'MESSAGE_ID': AUCTION_WORKER_SERVICE_AUCTION_CANCELED }) auction_document["current_stage"] = -100 auction_document["endDate"] = datetime.now( TIMEZONE).isoformat() LOGGER.info("Change auction {} status to 'canceled'".format( self.context['auction_doc_id']), extra={ 'MESSAGE_ID': AUCTION_WORKER_SERVICE_AUCTION_STATUS_CANCELED }) else: LOGGER.info( "Auction {} not found".format(self.context['auction_doc_id']), extra={'MESSAGE_ID': AUCTION_WORKER_SERVICE_AUCTION_NOT_FOUND})
def add_bid(self, current_stage, bid): LOGGER.info( '------------------ Adding bid ------------------', ) # Updating auction document with bid data with utils.update_auction_document(self.context, self.database) as auction_document: try: bid['bidder_name'] = self.context['bids_mapping'].get(bid['bidder_id'], False) result = utils.prepare_results_stage(**bid) auction_document['stages'][current_stage].update(result) results = auction_document['results'] bid_index = next((i for i, res in enumerate(results) if res['bidder_id'] == bid['bidder_id']), None) if bid_index is not None: results[bid_index] = result else: results.append(result) auction_document['results'] = sorting_by_amount(results) except Exception as e: LOGGER.fatal( "Exception during adding bid. " "Error: {}".format(e) ) return e self.end_bid_stage(bid) return True
def post_announce(self): self.context['auction_document'] = self.database.get_auction_document( self.context['auction_doc_id']) auction = self.datasource.get_data(with_credentials=True) bids_information = utils.get_bids(auction) with utils.update_auction_document(self.context, self.database) as auction_document: utils.open_bidders_name(auction_document, bids_information)
def end_bid_stage(self, bid): request_id = generate_request_id() LOGGER.info( '---------------- End Bids Stage ----------------', extra={"JOURNAL_REQUEST_ID": request_id, "MESSAGE_ID": AUCTION_WORKER_SERVICE_END_BID_STAGE} ) # Cleaning up preplanned jobs SCHEDULER.remove_all_jobs() # Update auction protocol auction_protocol = approve_auction_protocol_info_on_bids_stage( self.context['auction_document'], self.context['auction_protocol'] ) self.context['auction_protocol'] = auction_protocol with utils.update_auction_document(self.context, self.database) as auction_document: # Creating new stages bid_document = { 'value': {'amount': bid['amount']}, 'minimalStep': auction_document['minimalStep'] } pause, main_round = utils.prepare_auction_stages( utils.convert_datetime(bid['time']), bid_document, self.context.get('deadline'), fast_forward=self.context['worker_defaults'].get('sandbox_mode', False) ) auction_document['stages'].append(pause) if main_round: auction_document['stages'].append(main_round) # Updating current stage auction_document["current_stage"] += 1 LOGGER.info('---------------- Start stage {0} ----------------'.format( self.context['auction_document']["current_stage"]), extra={"JOURNAL_REQUEST_ID": request_id, "MESSAGE_ID": AUCTION_WORKER_SERVICE_START_NEXT_STAGE} ) # Adding jobs to scheduler deadline = self.context.get('deadline') if main_round: round_start_date = utils.convert_datetime(main_round['start']) round_end_date = get_round_ending_time( round_start_date, ROUND_DURATION, deadline ) self.job_service.add_pause_job(round_start_date) self.job_service.add_ending_main_round_job(round_end_date) else: self.job_service.add_ending_main_round_job(deadline)
def add_bid(self, current_stage, bid): LOGGER.info('------------------ Adding bid ------------------', ) # Updating auction document with bid data with utils.update_auction_document(self.context, self.database) as auction_document: bid['bidder_name'] = self.context['bids_mapping'].get( bid['bidder_id'], False) self.context['_bids_data'][bid['bidder_id']].append(deepcopy(bid)) result = utils.prepare_results_stage(**bid) auction_document['stages'][current_stage].update(result) auction_document['results'].append(result) self.end_bid_stage(bid)
def switch_to_next_stage(self): request_id = generate_request_id() with lock_server(self.context['server_actions']): with update_auction_document(self.context, self.database) as auction_document: auction_document["current_stage"] += 1 LOGGER.info('---------------- Start stage {0} ----------------'.format( self.context['auction_document']["current_stage"]), extra={ "JOURNAL_REQUEST_ID": request_id, "MESSAGE_ID": AUCTION_WORKER_SERVICE_START_NEXT_STAGE })
def end_bid_stage(self, bid): request_id = generate_request_id() LOGGER.info('---------------- End Bids Stage ----------------', extra={ "JOURNAL_REQUEST_ID": request_id, "MESSAGE_ID": AUCTION_WORKER_SERVICE_END_BID_STAGE }) # Cleaning up preplanned jobs SCHEDULER.remove_all_jobs() with utils.update_auction_document(self.context, self.database) as auction_document: # Creating new stages bid_document = { 'value': { 'amount': bid['amount'] }, 'minimalStep': auction_document['minimalStep'] } pause, main_round = utils.prepare_auction_stages( utils.convert_datetime(bid['time']), bid_document) auction_document['stages'].append(pause) if main_round: auction_document['stages'].append(main_round) # Updating current stage auction_document["current_stage"] += 1 LOGGER.info('---------------- Start stage {0} ----------------'.format( self.context['auction_document']["current_stage"]), extra={ "JOURNAL_REQUEST_ID": request_id, "MESSAGE_ID": AUCTION_WORKER_SERVICE_START_NEXT_STAGE }) # Adding jobs to scheduler deadline = set_specific_hour(datetime.now(TIMEZONE), DEADLINE_HOUR) if main_round: round_start_date = utils.convert_datetime(main_round['start']) round_end_date = get_round_ending_time(round_start_date, ROUND_DURATION, deadline) self.job_service.add_pause_job(round_start_date) self.job_service.add_ending_main_round_job(round_end_date) else: self.job_service.add_ending_main_round_job(deadline)
def schedule_auction(self): self.context['auction_document'] = self.database.get_auction_document( self.context['auction_doc_id']) with utils.update_auction_document(self.context, self.database) as auction_document: if self.debug: LOGGER.info("Get _auction_data from auction_document") self._auction_data = auction_document.get( 'test_auction_data', {}) self.synchronize_auction_info() self.context['auction_data'] = deepcopy(self._auction_data) self.context['bidders_data'] = deepcopy(self.bidders_data) self.context['bids_mapping'] = deepcopy(self.bids_mapping) self.auction_protocol = utils.prepare_auction_protocol( self.context) self.context['auction_protocol'] = deepcopy(self.auction_protocol) if self.context['auction_document'].get( 'submissionMethodDetails') == 'quick': utils.set_relative_deadline(self.context, self.startDate, SANDBOX_AUCTION_DURATION) else: utils.set_absolute_deadline(self.context, self.startDate) # Add job that starts auction server SCHEDULER.add_job( self.start_auction, 'date', run_date=utils.convert_datetime( self.context['auction_document']['stages'][0]['start']), name="Start of Auction", id="auction:start") # Add job that switch current_stage to round stage start = utils.convert_datetime( self.context['auction_document']['stages'][1]['start']) self.job_service.add_pause_job(start) # Add job that end auction start = utils.convert_datetime( self.context['auction_document']['stages'][1] ['start']) + timedelta(seconds=ROUND_DURATION) self.job_service.add_ending_main_round_job(start) self.server = run_server( self, None, # TODO: add mapping expire LOGGER) self.context['server'] = self.server
def reschedule_auction(self): self.context['auction_document'] = self.database.get_auction_document( self.context['auction_doc_id']) if self.context['auction_document']: with utils.update_auction_document( self.context, self.database) as auction_document: LOGGER.info( "Auction {} has not started and will be rescheduled". format(self.context['auction_doc_id']), extra={ 'MESSAGE_ID': AUCTION_WORKER_SERVICE_AUCTION_RESCHEDULE }) auction_document["current_stage"] = -101 else: LOGGER.info( "Auction {} not found".format(self.context['auction_doc_id']), extra={'MESSAGE_ID': AUCTION_WORKER_SERVICE_AUCTION_NOT_FOUND})
def start_auction(self): request_id = generate_request_id() self.auction_protocol['timeline']['auction_start'][ 'time'] = datetime.now(TIMEZONE).isoformat() LOGGER.info('---------------- Start auction ----------------', extra={ "JOURNAL_REQUEST_ID": request_id, "MESSAGE_ID": AUCTION_WORKER_SERVICE_END_FIRST_PAUSE }) self.synchronize_auction_info() with utils.lock_server( self.context['server_actions']), utils.update_auction_document( self.context, self.database) as auction_document: self._prepare_initial_bids(auction_document) auction_document["current_stage"] = 0 LOGGER.info("Switched current stage to {}".format( auction_document['current_stage']))
def schedule_auction(self): self.context['auction_document'] = self.database.get_auction_document( self.context['auction_doc_id']) with utils.update_auction_document(self.context, self.database) as auction_document: if self.debug: LOGGER.info("Get _auction_data from auction_document") self._auction_data = auction_document.get( 'test_auction_data', {}) self.synchronize_auction_info() self.audit = utils.prepare_audit() self.context['audit'] = deepcopy(self.audit) self.context['auction_data'] = deepcopy(self._auction_data) self.context['bidders_data'] = deepcopy(self.bidders_data) self.context['bids_mapping'] = deepcopy(self.bids_mapping) # Add job that starts auction server SCHEDULER.add_job( self.start_auction, 'date', run_date=utils.convert_datetime( self.context['auction_document']['stages'][0]['start']), name="Start of Auction", id="auction:start") # Add job that switch current_stage to round stage start = utils.convert_datetime( self.context['auction_document']['stages'][1]['start']) self.job_service.add_pause_job(start) # Add job that end auction start = utils.convert_datetime( self.context['auction_document']['stages'][1] ['start']) + timedelta(seconds=ROUND_DURATION) self.job_service.add_ending_main_round_job(start) self.server = run_server( self, None, # TODO: add mapping expire LOGGER) self.context['server'] = self.server