def fail_queue(request): # render the page error_status = StatusUtils().get_error() failed_jobs = ReductionRun.objects.filter(Q(status=error_status) & Q(hidden_in_failviewer=False)).order_by('-created') context_dictionary = { 'queue' : failed_jobs , 'status_success' : StatusUtils().get_completed() , 'status_failed' : StatusUtils().get_error() } if request.method == 'POST': # perform the specified action action = request.POST.get("action", "default") selectedRunString = request.POST.get("selectedRuns", []) selectedRuns = json.loads(selectedRunString) try: for run in selectedRuns: runNumber = int(run[0]) runVersion = int(run[1]) RBNumber = int(run[2]) experiment = Experiment.objects.filter(reference_number=RBNumber).first() reductionRun = ReductionRun.objects.get(experiment=experiment, run_number=runNumber, run_version=runVersion) if action == "hide": reductionRun.hidden_in_failviewer = True reductionRun.save() elif action == "rerun": highest_version = max([int(runL[1]) for runL in selectedRuns if int(runL[0]) == runNumber]) if runVersion != highest_version: continue # do not run multiples of the same run ReductionRunUtils().cancelRun(reductionRun) reductionRun.cancel = False new_job = ReductionRunUtils().createRetryRun(reductionRun) try: MessagingUtils().send_pending(new_job) except Exception as e: new_job.delete() raise e elif action == "cancel": ReductionRunUtils().cancelRun(reductionRun) elif action == "default": pass except Exception as e: failStr = "Selected action failed: %s %s" % (type(e).__name__, e) logger.info("Failed to carry out fail_queue action - " + failStr) context_dictionary["message"] = failStr return context_dictionary
def retryRun(self, reductionRun, retryIn): if (reductionRun.cancel): logger.info("Cancelling run retry") return logger.info("Retrying run in %i seconds" % retryIn) new_job = ReductionRunUtils().createRetryRun(reductionRun, delay=retryIn) try: MessagingUtils().send_pending(new_job, delay=retryIn*1000) # seconds to ms except Exception as e: new_job.delete() raise e
def run_confirmation(request, instrument=None): if request.method != 'POST': return redirect('instrument_summary', instrument=instrument.name) # POST instrument = Instrument.objects.get(name=instrument) run_numbers = [] if 'run_number' in request.POST: run_numbers.append(int(request.POST.get('run_number'))) else: range_string = request.POST.get('run_range').split(',') # Expand list for item in range_string: if '-' in item: split_range = item.split('-') run_numbers.extend( range(int(split_range[0]), int(split_range[1]) + 1) ) # because this is a range, the end bound is exclusive! else: run_numbers.append(int(item)) # Make sure run numbers are distinct run_numbers = set(run_numbers) queued_status = StatusUtils().get_queued() queue_count = ReductionRun.objects.filter(instrument=instrument, status=queued_status).count() context_dictionary = { 'runs': [], 'variables': None, 'queued': queue_count, } # Check that RB numbers are the same rb_number = ReductionRun.objects.filter( instrument=instrument, run_number__in=run_numbers).values_list('experiment__reference_number', flat=True).distinct() if len(rb_number) > 1: context_dictionary[ 'error'] = 'Runs span multiple experiment numbers (' + ','.join( str(i) for i in rb_number) + ') please select a different range.' for run_number in run_numbers: old_reduction_run = ReductionRun.objects.filter( run_number=run_number).order_by('-run_version').first() # Check old run exists if old_reduction_run is None: context_dictionary['error'] = "Run number " + str( run_number) + " doesn't exist." use_current_script = request.POST.get('use_current_script', u"true").lower() == u"true" if use_current_script: script_text = InstrumentVariablesUtils().get_current_script_text( instrument.name)[0] default_variables = InstrumentVariablesUtils( ).get_default_variables(instrument.name) else: script_text = old_reduction_run.script default_variables = old_reduction_run.run_variables.all() new_variables = [] for key, value in request.POST.iteritems(): if 'var-' in key: name = None if 'var-advanced-' in key: name = key.replace('var-advanced-', '').replace('-', ' ') is_advanced = True if 'var-standard-' in key: name = key.replace('var-standard-', '').replace('-', ' ') is_advanced = False if name is not None: default_var = next( (x for x in default_variables if x.name == name), None) if not default_var: continue if len(value) > InstrumentVariable._meta.get_field( 'value').max_length: context_dictionary['error'] = 'Value given in ' + str( name) + ' is too long.' variable = RunVariable(name=default_var.name, value=value, is_advanced=is_advanced, type=default_var.type, help_text=default_var.help_text) new_variables.append(variable) if len(new_variables) == 0: context_dictionary[ 'error'] = 'No variables were found to be submitted.' # User can choose whether to overwrite with the re-run or create new data if request.POST.get('overwrite_checkbox') == 'on': overwrite_previous_data = True else: overwrite_previous_data = False if 'error' in context_dictionary: return context_dictionary run_description = request.POST.get('run_description') new_job = ReductionRunUtils().createRetryRun( old_reduction_run, script=script_text, overwrite=overwrite_previous_data, variables=new_variables, username=request.user.username, description=run_description) try: MessagingUtils().send_pending(new_job) context_dictionary['runs'].append(new_job) context_dictionary['variables'] = new_variables except Exception as e: new_job.delete() context_dictionary['error'] = 'Failed to send new job. (%s)' % str( e) return context_dictionary
def run_confirmation(request, instrument): """ Handles request for user to confirm re-run """ if request.method != 'POST': return redirect('instrument_summary', instrument=instrument.name) # POST # pylint:disable=no-member instrument = Instrument.objects.get(name=instrument) range_string = request.POST.get('run_range') queued_status = StatusUtils().get_queued() # pylint:disable=no-member queue_count = ReductionRun.objects.filter(instrument=instrument, status=queued_status).count() context_dictionary = { 'runs': [], 'variables': None, 'queued': queue_count, } try: run_numbers = input_processing.parse_user_run_numbers(range_string) except SyntaxError as exception: context_dictionary['error'] = exception.msg return context_dictionary # Determine user level to set a maximum limit to the number of runs that can be re-queued if request.user.is_superuser: max_runs = 500 elif request.user.is_staff: max_runs = 50 else: max_runs = 20 if len(run_numbers) > max_runs: context_dictionary["error"] = "{0} runs were requested, but only {1} runs can be " \ "queued at a time".format(len(run_numbers), max_runs) return context_dictionary # Check that RB numbers are the same for the range entered # pylint:disable=no-member rb_number = ReductionRun.objects.filter(instrument=instrument, run_number__in=run_numbers) \ .values_list('experiment__reference_number', flat=True).distinct() if len(rb_number) > 1: context_dictionary['error'] = 'Runs span multiple experiment numbers ' \ '(' + ','.join(str(i) for i in rb_number) + ')' \ ' please select a different range.' return context_dictionary for run_number in run_numbers: # pylint:disable=no-member matching_previous_runs_queryset = ReductionRun.objects.\ filter(instrument=instrument, run_number=run_number).order_by('-run_version') most_recent_previous_run = matching_previous_runs_queryset.first() # Check old run exists if most_recent_previous_run is None: context_dictionary['error'] = "Run number %s hasn't been" \ "ran by autoreduction yet." % str(run_number) # Check it is not currently queued queued_runs = matching_previous_runs_queryset.filter( status=queued_status).first() if queued_runs is not None: context_dictionary['error'] = "Run number {0} is already queued to run".\ format(queued_runs.run_number) return context_dictionary use_current_script = request.POST.get('use_current_script', u"true").lower() == u"true" if use_current_script: script_text = InstrumentVariablesUtils().get_current_script_text( instrument.name)[0] default_variables = InstrumentVariablesUtils( ).get_default_variables(instrument.name) else: script_text = most_recent_previous_run.script default_variables = most_recent_previous_run.run_variables.all() new_variables = [] for key, value in list(request.POST.items()): if 'var-' in key: name = None if 'var-advanced-' in key: name = key.replace('var-advanced-', '').replace('-', ' ') is_advanced = True if 'var-standard-' in key: name = key.replace('var-standard-', '').replace('-', ' ') is_advanced = False if name is not None: default_var = next( (x for x in default_variables if x.name == name), None) if not default_var: continue # pylint:disable=protected-access,no-member if len(value) > InstrumentVariable._meta.get_field( 'value').max_length: context_dictionary['error'] = 'Value given in {} is too long.'\ .format(str(name)) variable = RunVariable(name=default_var.name, value=value, is_advanced=is_advanced, type=default_var.type, help_text=default_var.help_text) new_variables.append(variable) if not new_variables: context_dictionary[ 'error'] = 'No variables were found to be submitted.' # User can choose whether to overwrite with the re-run or create new data overwrite_previous_data = bool( request.POST.get('overwrite_checkbox') == 'on') if 'error' in context_dictionary: return context_dictionary run_description = request.POST.get('run_description') max_desc_len = 200 if len(run_description) > max_desc_len: context_dictionary["error"] = "The description contains {0} characters, " \ "a maximum of {1} are allowed".\ format(len(run_description), max_desc_len) return context_dictionary new_job = ReductionRunUtils().createRetryRun( user_id=request.user.id, reduction_run=most_recent_previous_run, script=script_text, overwrite=overwrite_previous_data, variables=new_variables, description=run_description) try: MessagingUtils().send_pending(new_job) context_dictionary['runs'].append(new_job) context_dictionary['variables'] = new_variables # pylint:disable=broad-except except Exception as exception: new_job.delete() context_dictionary['error'] = 'Failed to send new job. (%s)' % str( exception) return context_dictionary
def run_confirmation(request, instrument=None): if request.method != 'POST': return redirect('instrument_summary', instrument=instrument.name) # POST instrument = Instrument.objects.get(name=instrument) run_numbers = [] if 'run_number' in request.POST: run_numbers.append(int(request.POST.get('run_number'))) else: range_string = request.POST.get('run_range').split(',') # Expand list for item in range_string: if '-' in item: split_range = item.split('-') run_numbers.extend(range(int(split_range[0]), int(split_range[1])+1)) # because this is a range, the end bound is exclusive! else: run_numbers.append(int(item)) # Make sure run numbers are distinct run_numbers = set(run_numbers) queued_status = StatusUtils().get_queued() queue_count = ReductionRun.objects.filter(instrument=instrument, status=queued_status).count() context_dictionary = { 'runs' : [], 'variables' : None, 'queued' : queue_count, } # Check that RB numbers are the same rb_number = ReductionRun.objects.filter(instrument=instrument, run_number__in=run_numbers).values_list('experiment__reference_number', flat=True).distinct() if len(rb_number) > 1: context_dictionary['error'] = 'Runs span multiple experiment numbers (' + ','.join(str(i) for i in rb_number) + ') please select a different range.' for run_number in run_numbers: old_reduction_run = ReductionRun.objects.filter(run_number=run_number).order_by('-run_version').first() use_current_script = request.POST.get('use_current_script', u"true").lower() == u"true" if use_current_script: script_text = InstrumentVariablesUtils().get_current_script_text(instrument.name)[0] default_variables = InstrumentVariablesUtils().get_default_variables(instrument.name) else: script_text = old_reduction_run.script default_variables = old_reduction_run.run_variables.all() new_variables = [] for key,value in request.POST.iteritems(): if 'var-' in key: name = None if 'var-advanced-' in key: name = key.replace('var-advanced-', '').replace('-', ' ') is_advanced = True if 'var-standard-' in key: name = key.replace('var-standard-', '').replace('-', ' ') is_advanced = False if name is not None: default_var = next((x for x in default_variables if x.name == name), None) if not default_var: continue if len(value) > InstrumentVariable._meta.get_field('value').max_length: context_dictionary['error'] = 'Value given in ' + str(name) + ' is too long.' variable = RunVariable( name = default_var.name , value = value , is_advanced = is_advanced , type = default_var.type , help_text = default_var.help_text ) new_variables.append(variable) if len(new_variables) == 0: context_dictionary['error'] = 'No variables were found to be submitted.' if 'error' in context_dictionary: return context_dictionary new_job = ReductionRunUtils().createRetryRun(old_reduction_run, script=script_text, variables=new_variables, username=request.user.username) try: MessagingUtils().send_pending(new_job) context_dictionary['runs'].append(new_job) context_dictionary['variables'] = new_variables except Exception as e: new_job.delete() context_dictionary['error'] = 'Failed to send new job. (%s)' % str(e) return context_dictionary