Skip to content

Commit 22d52f0

Browse files
josenavasantgonza
authored andcommitted
Transfer update delete templates (#2274)
* Moving update_sample_template * Transfer update_sample_template * Porting update prep template * Moving delete sample or column * Removing tests * Removing dispatchable and its tests * Updating interface to use the new functionality' * Adapting the prep template GUI * Submitting jobs * Fixing tests * Removing qiita_ware/context.py * flake8ing * Fixing _system_call * Safeguarding the call to rollback * Unmasking more errors * Forcing different connections on different processes * Moving job completion to internal plugin structure * Removing unused code * Forcing the creation of a new transaction on the jobs * Fixing tests * forcing the commit * Fixing all tests * Addressing @antgonza's comments * Addressing @antgonza's comment * Addressing @ElDeveloper's comments
1 parent dc7f78c commit 22d52f0

25 files changed

+667
-914
lines changed

.travis.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,17 @@ install:
4141
- mkdir ~/.qiita_plugins
4242
- cp $PWD/qiita_core/support_files/BIOM\ type_2.1.4.conf ~/.qiita_plugins
4343
before_script:
44-
# Some of the tests rely on the plugin system to complete successfuly.
45-
# Thus, we need a qiita webserver running to be able to execute the tests.
46-
- export MOI_CONFIG_FP=`pwd`/qiita_core/support_files/config_test.cfg
4744
# EBI, see the end of before_install about why this block is commented out
4845
# - if [ ${TRAVIS_PULL_REQUEST} == "false" ]; then
4946
# export QIITA_CONFIG_FP=`pwd`/qiita_core/support_files/config_test_travis.cfg;
50-
# export MOI_CONFIG_FP=`pwd`/qiita_core/support_files/config_test_travis.cfg;
5147
# fi
5248
- qiita-env make --no-load-ontologies
5349
- qiita-test-install
5450
script:
55-
- sleep 5
51+
# Some of the tests rely on the plugin system to complete successfuly.
52+
# Thus, we need a qiita webserver running to be able to execute the tests.
5653
- qiita pet webserver --no-build-docs start &
54+
- sleep 5
5755
- QIITA_PID=$!
5856
- nosetests $COVER_PACKAGE --with-doctest --with-coverage --with-timer -v --cover-package=$COVER_PACKAGE
5957
- kill $QIITA_PID

qiita_core/testing.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,7 @@ def wait_for_prep_information_job(prep_id, raise_if_none=True):
3838
if res is not None:
3939
payload = loads(res)
4040
job_id = payload['job_id']
41-
if payload['is_qiita_job']:
42-
wait_for_processing_job(job_id)
43-
else:
44-
redis_info = loads(r_client.get(job_id))
45-
while redis_info['status_msg'] == 'Running':
46-
sleep(0.5)
47-
redis_info = loads(r_client.get(job_id))
48-
sleep(0.5)
41+
wait_for_processing_job(job_id)
4942

5043

5144
def wait_for_processing_job(job_id):

qiita_db/commands.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
from functools import partial
1010
from future import standard_library
1111
from json import loads
12-
from sys import exc_info
13-
import traceback
1412

1513
import qiita_db as qdb
1614

@@ -270,27 +268,3 @@ def update_artifact_from_cmd(filepaths, filepath_types, artifact_id):
270268
qdb.sql_connection.TRN.execute()
271269

272270
return artifact
273-
274-
275-
def complete_job_cmd(job_id, payload):
276-
"""Completes the given job
277-
278-
Parameters
279-
----------
280-
job_id : str
281-
The job id
282-
payload : str
283-
JSON string with the payload to complete the job
284-
"""
285-
payload = loads(payload)
286-
if payload['success']:
287-
artifacts = payload['artifacts']
288-
error = None
289-
else:
290-
artifacts = None
291-
error = payload['error']
292-
job = qdb.processing_job.ProcessingJob(job_id)
293-
try:
294-
job.complete(payload['success'], artifacts, error)
295-
except:
296-
job._set_error(traceback.format_exception(*exc_info()))

qiita_db/environment_manager.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from future.utils import viewitems
1818

1919
from qiita_core.exceptions import QiitaEnvironmentError
20-
from qiita_core.qiita_settings import qiita_config
20+
from qiita_core.qiita_settings import qiita_config, r_client
2121
import qiita_db as qdb
2222

2323

@@ -318,6 +318,8 @@ def drop_and_rebuild_tst_database():
318318

319319
qdb.sql_connection.TRN.execute()
320320

321+
r_client.flushdb()
322+
321323

322324
def reset_test_database(wrapped_fn):
323325
"""Decorator that drops the qiita schema, rebuilds and repopulates the

qiita_db/handlers/processing_job.py

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
# -----------------------------------------------------------------------------
88

99
from json import loads
10-
from multiprocessing import Process
1110

1211
from tornado.web import HTTPError
1312

@@ -46,26 +45,6 @@ def _get_job(job_id):
4645
return job
4746

4847

49-
def _job_completer(job_id, payload):
50-
"""Completes a job
51-
52-
Parameters
53-
----------
54-
job_id : str
55-
The job to complete
56-
payload : str
57-
The JSON string with the parameters of the HTTP POST request that is
58-
completing the job
59-
"""
60-
import qiita_db as qdb
61-
62-
success, error = qdb.processing_job.private_job_submitter(
63-
"Complete job %s" % job_id, 'complete_job', [job_id, payload])
64-
if not success:
65-
job = qdb.processing_job.ProcessingJob(job_id)
66-
job.complete(False, error=error)
67-
68-
6948
class JobHandler(OauthBaseHandler):
7049
@authenticate_oauth
7150
def get(self, job_id):
@@ -158,10 +137,14 @@ def post(self, job_id):
158137
raise HTTPError(
159138
403, "Can't complete job: not in a running state")
160139

161-
p = Process(target=_job_completer,
162-
args=(job_id, self.request.body))
163-
p.start()
164-
# safe_submit(job.user.email, _job_completer, job_id, payload)
140+
qiita_plugin = qdb.software.Software.from_name_and_version(
141+
'Qiita', 'alpha')
142+
cmd = qiita_plugin.get_command('complete_job')
143+
params = qdb.software.Parameters.load(
144+
cmd, values_dict={'job_id': job_id,
145+
'payload': self.request.body})
146+
job = qdb.processing_job.ProcessingJob.create(job.user, params)
147+
job.submit()
165148

166149
self.finish()
167150

qiita_db/processing_job.py

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -53,45 +53,23 @@ def _system_call(cmd):
5353
return stdout, stderr, return_value
5454

5555

56-
def _job_submitter(job, cmd):
56+
def _job_submitter(job_id, cmd):
5757
"""Executes the commands `cmd` and updates the job in case of failure
5858
5959
Parameters
6060
----------
61-
job : qiita_db.processing_job.ProcesingJob
62-
The job that is executed by cmd
61+
job_id : str
62+
The job id that is executed by cmd
6363
cmd : str
6464
The command to execute the job
6565
"""
6666
std_out, std_err, return_value = _system_call(cmd)
6767
if return_value != 0:
68-
error = ("Error submitting job '%s':\nStd output:%s\nStd error:%s"
69-
% (job.id, std_out, std_err))
70-
job.complete(False, error=error)
71-
72-
73-
def private_job_submitter(job_name, command, args):
74-
"""Submits a private job
75-
76-
Parameters
77-
----------
78-
job_name : str
79-
The name of the job
80-
command: str
81-
The private command to be executed
82-
args: list of str
83-
The arguments to the private command
84-
"""
85-
86-
cmd = "%s '%s' %s %s" % (qiita_config.private_launcher,
87-
qiita_config.qiita_env, command,
88-
' '.join("'%s'" % a for a in args))
89-
std_out, std_err, return_value = _system_call(cmd)
90-
error = ""
91-
if return_value != 0:
92-
error = ("Can't submit private task '%s':\n"
93-
"Std output:%s\nStd error: %s" % (command, std_out, std_err))
94-
return (return_value == 0), error
68+
error = ("Error submitting job:\nStd output:%s\nStd error:%s"
69+
% (std_out, std_err))
70+
# Forcing the creation of a new connection
71+
qdb.sql_connection.create_new_transaction()
72+
ProcessingJob(job_id).complete(False, error=error)
9573

9674

9775
class ProcessingJob(qdb.base.QiitaObject):
@@ -347,14 +325,19 @@ def submit(self):
347325
QiitaDBOperationNotPermittedError
348326
If the job is not in 'waiting' or 'in_construction' status
349327
"""
350-
status = self.status
351-
if status not in {'in_construction', 'waiting'}:
352-
raise qdb.exceptions.QiitaDBOperationNotPermittedError(
353-
"Can't submit job, not in 'in_construction' or "
354-
"'waiting' status. Current status: %s" % status)
355-
self._set_status('queued')
328+
with qdb.sql_connection.TRN:
329+
status = self.status
330+
if status not in {'in_construction', 'waiting'}:
331+
raise qdb.exceptions.QiitaDBOperationNotPermittedError(
332+
"Can't submit job, not in 'in_construction' or "
333+
"'waiting' status. Current status: %s" % status)
334+
self._set_status('queued')
335+
# At this point we are going to involve other processes. We need
336+
# to commit the changes to the DB or the other processes will not
337+
# see these changes
338+
qdb.sql_connection.TRN.commit()
356339
cmd = self._generate_cmd()
357-
p = Process(target=_job_submitter, args=(self, cmd))
340+
p = Process(target=_job_submitter, args=(self.id, cmd))
358341
p.start()
359342

360343
def release(self):

qiita_db/sql_connection.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -646,9 +646,12 @@ def _raise_execution_error(self, sql, sql_args, error):
646646
"""
647647
self.rollback()
648648

649-
raise ValueError(
650-
"Error running SQL: %s. MSG: %s\n" % (
651-
errorcodes.lookup(error.pgcode), error.message))
649+
try:
650+
ec_lu = errorcodes.lookup(error.pgcode)
651+
raise ValueError(
652+
"Error running SQL: %s. MSG: %s\n" % (ec_lu, error.message))
653+
except KeyError:
654+
raise ValueError("Error running SQL query: %s" % error.message)
652655

653656
@_checker
654657
def add(self, sql, sql_args=None, many=False):
@@ -882,11 +885,13 @@ def rollback(self):
882885
# Reset the queries, the results and the index
883886
self._queries = []
884887
self._results = []
885-
try:
886-
self._connection.rollback()
887-
except Exception:
888-
self._connection.close()
889-
raise
888+
889+
if self._connection is not None and self._connection.closed == 0:
890+
try:
891+
self._connection.rollback()
892+
except Exception:
893+
self._connection.close()
894+
raise
890895
# Execute the post rollback functions
891896
self._funcs_executor(self._post_rollback_funcs, "rollback")
892897

@@ -937,3 +942,12 @@ def add_post_rollback_func(self, func, *args, **kwargs):
937942

938943
# Singleton pattern, create the transaction for the entire system
939944
TRN = Transaction()
945+
946+
947+
def create_new_transaction():
948+
"""Creates a new global transaction
949+
950+
This is needed when using multiprocessing
951+
"""
952+
global TRN
953+
TRN = Transaction()

qiita_db/support_files/patches/python_patches/58.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,24 @@
1414
qiita_plugin = Software.from_name_and_version('Qiita', 'alpha')
1515

1616
# Create the submit command for VAMPS command
17-
parameters = {'artifact': ['artifact:["Demultiplexed"]', None]}
17+
parameters = {'artifact': ['integer', None]}
1818
Command.create(qiita_plugin, "submit_to_VAMPS",
1919
"submits an artifact to VAMPS", parameters)
2020

2121
# Create the copy artifact command
22-
parameters = {'artifact': ['artifact:["Demultiplexed"]', None],
22+
parameters = {'artifact': ['integer', None],
2323
'prep_template': ['prep_template', None]}
2424
Command.create(qiita_plugin, "copy_artifact",
2525
"Creates a copy of an artifact", parameters)
2626

2727
# Create the submit command for EBI command
28-
parameters = {'artifact': ['artifact:["Demultiplexed"]', None],
28+
parameters = {'artifact': ['integer', None],
2929
'submission_type': ['choice:["ADD", "MODIFY"]', 'ADD']}
3030
Command.create(qiita_plugin, "submit_to_EBI",
3131
"submits an artifact to EBI", parameters)
3232

3333
# Create the submit command for delete_artifact
34-
parameters = {'artifact': ['artifact:["Demultiplexed"]', None]}
34+
parameters = {'artifact': ['integer', None]}
3535
Command.create(qiita_plugin, "delete_artifact",
3636
"Delete an artifact", parameters)
3737

@@ -41,3 +41,34 @@
4141
'is_mapping_file': ['boolean', True], 'data_type': ['string', None]}
4242
Command.create(qiita_plugin, "create_sample_template",
4343
"Create a sample template", parameters)
44+
45+
# Create the update sample template command
46+
parameters = {'study': ['integer', None], 'template_fp': ['string', None]}
47+
Command.create(qiita_plugin, "update_sample_template",
48+
"Updates the sample template", parameters)
49+
50+
# Create the delete sample template command
51+
parameters = {'study': ['integer', None]}
52+
Command.create(qiita_plugin, "delete_sample_template",
53+
"Deletes a sample template", parameters)
54+
55+
# Create the update prep template command
56+
parameters = {'prep_template': ['integer', None],
57+
'template_fp': ['string', None]}
58+
Command.create(qiita_plugin, "update_prep_template",
59+
"Updates the prep template", parameters)
60+
61+
# Create the delete sample or column command
62+
parameters = {
63+
'obj_class': ['choice:["SampleTemplate", "PrepTemplate"]', None],
64+
'obj_id': ['integer', None],
65+
'sample_or_col': ['choice:["samples", "columns"]', None],
66+
'name': ['string', None]}
67+
Command.create(qiita_plugin, "delete_sample_or_column",
68+
"Deletes a sample or a columns from the metadata",
69+
parameters)
70+
71+
# Create the command to complete a job
72+
parameters = {'job_id': ['string', None], 'payload': ['string', None]}
73+
Command.create(qiita_plugin, "complete_job", "Completes a given job",
74+
parameters)

0 commit comments

Comments
 (0)