We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
GridEngine provider mis-parses wall times, treating minutes as seconds
**Describe the bug**
The GridEngine system expects walltime in seconds, but parsl provides `10`, which leads to difficult-to-recognize errors relating to walltime errors.

**To Reproduce**
Steps to reproduce the behavior, for e.g:
1. Setup Parsl 0.9.0 with Python 3.6 on cluster
2. Run a sleep job with GridEngine provider
3. Watch the `qstat`, where you will see jobs disappear

**Expected behavior**
10 minute default walltime

**Environment**
 - OS: CentOS 7
 - Python version 3.6
 - Parsl version 0.9

**Distributed Environment**
- Where are you running the Parsl script from ? Login node

- Where do you need the workers to run ?Worker nodes on same network as login node

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `parsl/providers/grid_engine/grid_engine.py`
Content:
```
1 import logging
2 import os
3 import time
4 
5 from parsl.channels import LocalChannel
6 from parsl.providers.cluster_provider import ClusterProvider
7 from parsl.providers.grid_engine.template import template_string
8 from parsl.launchers import SingleNodeLauncher
9 from parsl.providers.provider_base import JobState, JobStatus
10 from parsl.utils import RepresentationMixin, wtime_to_minutes
11 
12 logger = logging.getLogger(__name__)
13 
14 translate_table = {
15     'qw': JobState.PENDING,
16     'hqw': JobState.PENDING,
17     'hrwq': JobState.PENDING,
18     'r': JobState.RUNNING,
19     's': JobState.FAILED,  # obsuspended
20     'ts': JobState.FAILED,
21     't': JobState.FAILED,  # Suspended by alarm
22     'eqw': JobState.FAILED,  # Error states
23     'ehqw': JobState.FAILED,  # ..
24     'ehrqw': JobState.FAILED,  # ..
25     'd': JobState.COMPLETED,
26     'dr': JobState.COMPLETED,
27     'dt': JobState.COMPLETED,
28     'drt': JobState.COMPLETED,
29     'ds': JobState.COMPLETED,
30     'drs': JobState.COMPLETED,
31 }
32 
33 
34 class GridEngineProvider(ClusterProvider, RepresentationMixin):
35     """A provider for the Grid Engine scheduler.
36 
37     Parameters
38     ----------
39     channel : Channel
40         Channel for accessing this provider. Possible channels include
41         :class:`~parsl.channels.LocalChannel` (the default),
42         :class:`~parsl.channels.SSHChannel`, or
43         :class:`~parsl.channels.SSHInteractiveLoginChannel`.
44     nodes_per_block : int
45         Nodes to provision per block.
46     min_blocks : int
47         Minimum number of blocks to maintain.
48     max_blocks : int
49         Maximum number of blocks to maintain.
50     parallelism : float
51         Ratio of provisioned task slots to active tasks. A parallelism value of 1 represents aggressive
52         scaling where as many resources as possible are used; parallelism close to 0 represents
53         the opposite situation in which as few resources as possible (i.e., min_blocks) are used.
54     walltime : str
55         Walltime requested per block in HH:MM:SS.
56     scheduler_options : str
57         String to prepend to the #$$ blocks in the submit script to the scheduler.
58     worker_init : str
59         Command to be run before starting a worker, such as 'module load Anaconda; source activate env'.
60     launcher : Launcher
61         Launcher for this provider. Possible launchers include
62         :class:`~parsl.launchers.SingleNodeLauncher` (the default),
63     """
64 
65     def __init__(self,
66                  channel=LocalChannel(),
67                  nodes_per_block=1,
68                  init_blocks=1,
69                  min_blocks=0,
70                  max_blocks=10,
71                  parallelism=1,
72                  walltime="00:10:00",
73                  scheduler_options='',
74                  worker_init='',
75                  launcher=SingleNodeLauncher()):
76         label = 'grid_engine'
77         super().__init__(label,
78                          channel,
79                          nodes_per_block,
80                          init_blocks,
81                          min_blocks,
82                          max_blocks,
83                          parallelism,
84                          walltime,
85                          launcher)
86         self.scheduler_options = scheduler_options
87         self.worker_init = worker_init
88 
89         if launcher in ['srun', 'srun_mpi']:
90             logger.warning("Use of {} launcher is usually appropriate for Slurm providers. "
91                            "Recommended options include 'single_node' or 'aprun'.".format(launcher))
92 
93     def get_configs(self, command, tasks_per_node):
94         """Compose a dictionary with information for writing the submit script."""
95 
96         logger.debug("Requesting one block with {} nodes per block and {} tasks per node".format(
97             self.nodes_per_block, tasks_per_node))
98 
99         job_config = {}
100         job_config["submit_script_dir"] = self.channel.script_dir
101         job_config["nodes"] = self.nodes_per_block
102         job_config["walltime"] = wtime_to_minutes(self.walltime)
103         job_config["scheduler_options"] = self.scheduler_options
104         job_config["worker_init"] = self.worker_init
105         job_config["user_script"] = command
106 
107         job_config["user_script"] = self.launcher(command,
108                                                   tasks_per_node,
109                                                   self.nodes_per_block)
110         return job_config
111 
112     def submit(self, command, tasks_per_node, job_name="parsl.sge"):
113         ''' The submit method takes the command string to be executed upon
114         instantiation of a resource most often to start a pilot (such as IPP engine
115         or even Swift-T engines).
116 
117         Args :
118              - command (str) : The bash command string to be executed.
119              - tasks_per_node (int) : command invocations to be launched per node
120 
121         KWargs:
122              - job_name (str) : Human friendly name to be assigned to the job request
123 
124         Returns:
125              - A job identifier, this could be an integer, string etc
126 
127         Raises:
128              - ExecutionProviderException or its subclasses
129         '''
130 
131         # Set job name
132         job_name = "{0}.{1}".format(job_name, time.time())
133 
134         # Set script path
135         script_path = "{0}/{1}.submit".format(self.script_dir, job_name)
136         script_path = os.path.abspath(script_path)
137 
138         job_config = self.get_configs(command, tasks_per_node)
139 
140         logger.debug("Writing submit script")
141         self._write_submit_script(template_string, script_path, job_name, job_config)
142 
143         channel_script_path = self.channel.push_file(script_path, self.channel.script_dir)
144         cmd = "qsub -terse {0}".format(channel_script_path)
145         retcode, stdout, stderr = self.execute_wait(cmd, 10)
146 
147         if retcode == 0:
148             for line in stdout.split('\n'):
149                 job_id = line.strip()
150                 if not job_id:
151                     continue
152                 self.resources[job_id] = {'job_id': job_id, 'status': JobStatus(JobState.PENDING)}
153                 return job_id
154         else:
155             print("[WARNING!!] Submission of command to scale_out failed")
156             logger.error("Retcode:%s STDOUT:%s STDERR:%s", retcode, stdout.strip(), stderr.strip())
157 
158     def _status(self):
159         ''' Get the status of a list of jobs identified by the job identifiers
160         returned from the submit request.
161 
162         Returns:
163              - A list of JobStatus objects corresponding to each job_id in the job_ids list.
164 
165         Raises:
166              - ExecutionProviderException or its subclasses
167 
168         '''
169 
170         cmd = "qstat"
171 
172         retcode, stdout, stderr = self.execute_wait(cmd)
173 
174         # Execute_wait failed. Do no update
175         if retcode != 0:
176             return
177 
178         jobs_missing = list(self.resources.keys())
179         for line in stdout.split('\n'):
180             parts = line.split()
181             if parts and parts[0].lower().lower() != 'job-id' \
182                     and not parts[0].startswith('----'):
183                 job_id = parts[0]
184                 status = translate_table.get(parts[4].lower(), JobState.UNKNOWN)
185                 if job_id in self.resources:
186                     self.resources[job_id]['status'] = status
187                     jobs_missing.remove(job_id)
188 
189         # Filling in missing blanks for jobs that might have gone missing
190         # we might lose some information about why the jobs failed.
191         for missing_job in jobs_missing:
192             self.resources[missing_job]['status'] = JobStatus(JobState.COMPLETED)
193 
194     def cancel(self, job_ids):
195         ''' Cancels the resources identified by the job_ids provided by the user.
196 
197         Args:
198              - job_ids (list): A list of job identifiers
199 
200         Returns:
201              - A list of status from cancelling the job which can be True, False
202 
203         Raises:
204              - ExecutionProviderException or its subclasses
205         '''
206 
207         job_id_list = ' '.join(job_ids)
208         cmd = "qdel {}".format(job_id_list)
209         retcode, stdout, stderr = self.execute_wait(cmd, 3)
210 
211         rets = None
212         if retcode == 0:
213             for jid in job_ids:
214                 self.resources[jid]['status'] = JobStatus(JobState.COMPLETED)
215             rets = [True for i in job_ids]
216         else:
217             rets = [False for i in job_ids]
218 
219         return rets
220
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/parsl/providers/grid_engine/grid_engine.py b/parsl/providers/grid_engine/grid_engine.py
--- a/parsl/providers/grid_engine/grid_engine.py
+++ b/parsl/providers/grid_engine/grid_engine.py
@@ -7,7 +7,7 @@
 from parsl.providers.grid_engine.template import template_string
 from parsl.launchers import SingleNodeLauncher
 from parsl.providers.provider_base import JobState, JobStatus
-from parsl.utils import RepresentationMixin, wtime_to_minutes
+from parsl.utils import RepresentationMixin
 
 logger = logging.getLogger(__name__)
 
@@ -99,7 +99,7 @@
         job_config = {}
         job_config["submit_script_dir"] = self.channel.script_dir
         job_config["nodes"] = self.nodes_per_block
-        job_config["walltime"] = wtime_to_minutes(self.walltime)
+        job_config["walltime"] = self.walltime
         job_config["scheduler_options"] = self.scheduler_options
         job_config["worker_init"] = self.worker_init
         job_config["user_script"] = command

{"golden_diff": "diff --git a/parsl/providers/grid_engine/grid_engine.py b/parsl/providers/grid_engine/grid_engine.py\n--- a/parsl/providers/grid_engine/grid_engine.py\n+++ b/parsl/providers/grid_engine/grid_engine.py\n@@ -7,7 +7,7 @@\n from parsl.providers.grid_engine.template import template_string\n from parsl.launchers import SingleNodeLauncher\n from parsl.providers.provider_base import JobState, JobStatus\n-from parsl.utils import RepresentationMixin, wtime_to_minutes\n+from parsl.utils import RepresentationMixin\n \n logger = logging.getLogger(__name__)\n \n@@ -99,7 +99,7 @@\n         job_config = {}\n         job_config[\"submit_script_dir\"] = self.channel.script_dir\n         job_config[\"nodes\"] = self.nodes_per_block\n-        job_config[\"walltime\"] = wtime_to_minutes(self.walltime)\n+        job_config[\"walltime\"] = self.walltime\n         job_config[\"scheduler_options\"] = self.scheduler_options\n         job_config[\"worker_init\"] = self.worker_init\n         job_config[\"user_script\"] = command\n", "issue": "GridEngine provider mis-parses wall times, treating minutes as seconds\n**Describe the bug**\r\nThe GridEngine system expects walltime in seconds, but parsl provides `10`, which leads to difficult-to-recognize errors relating to walltime errors.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior, for e.g:\r\n1. Setup Parsl 0.9.0 with Python 3.6 on cluster\r\n2. Run a sleep job with GridEngine provider\r\n3. Watch the `qstat`, where you will see jobs disappear\r\n\r\n**Expected behavior**\r\n10 minute default walltime\r\n\r\n**Environment**\r\n - OS: CentOS 7\r\n - Python version 3.6\r\n - Parsl version 0.9\r\n\r\n**Distributed Environment**\r\n- Where are you running the Parsl script from ? Login node\r\n\r\n- Where do you need the workers to run ?Worker nodes on same network as login node\n", "before_files": [{"content": "import logging\nimport os\nimport time\n\nfrom parsl.channels import LocalChannel\nfrom parsl.providers.cluster_provider import ClusterProvider\nfrom parsl.providers.grid_engine.template import template_string\nfrom parsl.launchers import SingleNodeLauncher\nfrom parsl.providers.provider_base import JobState, JobStatus\nfrom parsl.utils import RepresentationMixin, wtime_to_minutes\n\nlogger = logging.getLogger(__name__)\n\ntranslate_table = {\n    'qw': JobState.PENDING,\n    'hqw': JobState.PENDING,\n    'hrwq': JobState.PENDING,\n    'r': JobState.RUNNING,\n    's': JobState.FAILED,  # obsuspended\n    'ts': JobState.FAILED,\n    't': JobState.FAILED,  # Suspended by alarm\n    'eqw': JobState.FAILED,  # Error states\n    'ehqw': JobState.FAILED,  # ..\n    'ehrqw': JobState.FAILED,  # ..\n    'd': JobState.COMPLETED,\n    'dr': JobState.COMPLETED,\n    'dt': JobState.COMPLETED,\n    'drt': JobState.COMPLETED,\n    'ds': JobState.COMPLETED,\n    'drs': JobState.COMPLETED,\n}\n\n\nclass GridEngineProvider(ClusterProvider, RepresentationMixin):\n    \"\"\"A provider for the Grid Engine scheduler.\n\n    Parameters\n    ----------\n    channel : Channel\n        Channel for accessing this provider. Possible channels include\n        :class:`~parsl.channels.LocalChannel` (the default),\n        :class:`~parsl.channels.SSHChannel`, or\n        :class:`~parsl.channels.SSHInteractiveLoginChannel`.\n    nodes_per_block : int\n        Nodes to provision per block.\n    min_blocks : int\n        Minimum number of blocks to maintain.\n    max_blocks : int\n        Maximum number of blocks to maintain.\n    parallelism : float\n        Ratio of provisioned task slots to active tasks. A parallelism value of 1 represents aggressive\n        scaling where as many resources as possible are used; parallelism close to 0 represents\n        the opposite situation in which as few resources as possible (i.e., min_blocks) are used.\n    walltime : str\n        Walltime requested per block in HH:MM:SS.\n    scheduler_options : str\n        String to prepend to the #$$ blocks in the submit script to the scheduler.\n    worker_init : str\n        Command to be run before starting a worker, such as 'module load Anaconda; source activate env'.\n    launcher : Launcher\n        Launcher for this provider. Possible launchers include\n        :class:`~parsl.launchers.SingleNodeLauncher` (the default),\n    \"\"\"\n\n    def __init__(self,\n                 channel=LocalChannel(),\n                 nodes_per_block=1,\n                 init_blocks=1,\n                 min_blocks=0,\n                 max_blocks=10,\n                 parallelism=1,\n                 walltime=\"00:10:00\",\n                 scheduler_options='',\n                 worker_init='',\n                 launcher=SingleNodeLauncher()):\n        label = 'grid_engine'\n        super().__init__(label,\n                         channel,\n                         nodes_per_block,\n                         init_blocks,\n                         min_blocks,\n                         max_blocks,\n                         parallelism,\n                         walltime,\n                         launcher)\n        self.scheduler_options = scheduler_options\n        self.worker_init = worker_init\n\n        if launcher in ['srun', 'srun_mpi']:\n            logger.warning(\"Use of {} launcher is usually appropriate for Slurm providers. \"\n                           \"Recommended options include 'single_node' or 'aprun'.\".format(launcher))\n\n    def get_configs(self, command, tasks_per_node):\n        \"\"\"Compose a dictionary with information for writing the submit script.\"\"\"\n\n        logger.debug(\"Requesting one block with {} nodes per block and {} tasks per node\".format(\n            self.nodes_per_block, tasks_per_node))\n\n        job_config = {}\n        job_config[\"submit_script_dir\"] = self.channel.script_dir\n        job_config[\"nodes\"] = self.nodes_per_block\n        job_config[\"walltime\"] = wtime_to_minutes(self.walltime)\n        job_config[\"scheduler_options\"] = self.scheduler_options\n        job_config[\"worker_init\"] = self.worker_init\n        job_config[\"user_script\"] = command\n\n        job_config[\"user_script\"] = self.launcher(command,\n                                                  tasks_per_node,\n                                                  self.nodes_per_block)\n        return job_config\n\n    def submit(self, command, tasks_per_node, job_name=\"parsl.sge\"):\n        ''' The submit method takes the command string to be executed upon\n        instantiation of a resource most often to start a pilot (such as IPP engine\n        or even Swift-T engines).\n\n        Args :\n             - command (str) : The bash command string to be executed.\n             - tasks_per_node (int) : command invocations to be launched per node\n\n        KWargs:\n             - job_name (str) : Human friendly name to be assigned to the job request\n\n        Returns:\n             - A job identifier, this could be an integer, string etc\n\n        Raises:\n             - ExecutionProviderException or its subclasses\n        '''\n\n        # Set job name\n        job_name = \"{0}.{1}\".format(job_name, time.time())\n\n        # Set script path\n        script_path = \"{0}/{1}.submit\".format(self.script_dir, job_name)\n        script_path = os.path.abspath(script_path)\n\n        job_config = self.get_configs(command, tasks_per_node)\n\n        logger.debug(\"Writing submit script\")\n        self._write_submit_script(template_string, script_path, job_name, job_config)\n\n        channel_script_path = self.channel.push_file(script_path, self.channel.script_dir)\n        cmd = \"qsub -terse {0}\".format(channel_script_path)\n        retcode, stdout, stderr = self.execute_wait(cmd, 10)\n\n        if retcode == 0:\n            for line in stdout.split('\\n'):\n                job_id = line.strip()\n                if not job_id:\n                    continue\n                self.resources[job_id] = {'job_id': job_id, 'status': JobStatus(JobState.PENDING)}\n                return job_id\n        else:\n            print(\"[WARNING!!] Submission of command to scale_out failed\")\n            logger.error(\"Retcode:%s STDOUT:%s STDERR:%s\", retcode, stdout.strip(), stderr.strip())\n\n    def _status(self):\n        ''' Get the status of a list of jobs identified by the job identifiers\n        returned from the submit request.\n\n        Returns:\n             - A list of JobStatus objects corresponding to each job_id in the job_ids list.\n\n        Raises:\n             - ExecutionProviderException or its subclasses\n\n        '''\n\n        cmd = \"qstat\"\n\n        retcode, stdout, stderr = self.execute_wait(cmd)\n\n        # Execute_wait failed. Do no update\n        if retcode != 0:\n            return\n\n        jobs_missing = list(self.resources.keys())\n        for line in stdout.split('\\n'):\n            parts = line.split()\n            if parts and parts[0].lower().lower() != 'job-id' \\\n                    and not parts[0].startswith('----'):\n                job_id = parts[0]\n                status = translate_table.get(parts[4].lower(), JobState.UNKNOWN)\n                if job_id in self.resources:\n                    self.resources[job_id]['status'] = status\n                    jobs_missing.remove(job_id)\n\n        # Filling in missing blanks for jobs that might have gone missing\n        # we might lose some information about why the jobs failed.\n        for missing_job in jobs_missing:\n            self.resources[missing_job]['status'] = JobStatus(JobState.COMPLETED)\n\n    def cancel(self, job_ids):\n        ''' Cancels the resources identified by the job_ids provided by the user.\n\n        Args:\n             - job_ids (list): A list of job identifiers\n\n        Returns:\n             - A list of status from cancelling the job which can be True, False\n\n        Raises:\n             - ExecutionProviderException or its subclasses\n        '''\n\n        job_id_list = ' '.join(job_ids)\n        cmd = \"qdel {}\".format(job_id_list)\n        retcode, stdout, stderr = self.execute_wait(cmd, 3)\n\n        rets = None\n        if retcode == 0:\n            for jid in job_ids:\n                self.resources[jid]['status'] = JobStatus(JobState.COMPLETED)\n            rets = [True for i in job_ids]\n        else:\n            rets = [False for i in job_ids]\n\n        return rets\n", "path": "parsl/providers/grid_engine/grid_engine.py"}], "after_files": [{"content": "import logging\nimport os\nimport time\n\nfrom parsl.channels import LocalChannel\nfrom parsl.providers.cluster_provider import ClusterProvider\nfrom parsl.providers.grid_engine.template import template_string\nfrom parsl.launchers import SingleNodeLauncher\nfrom parsl.providers.provider_base import JobState, JobStatus\nfrom parsl.utils import RepresentationMixin\n\nlogger = logging.getLogger(__name__)\n\ntranslate_table = {\n    'qw': JobState.PENDING,\n    'hqw': JobState.PENDING,\n    'hrwq': JobState.PENDING,\n    'r': JobState.RUNNING,\n    's': JobState.FAILED,  # obsuspended\n    'ts': JobState.FAILED,\n    't': JobState.FAILED,  # Suspended by alarm\n    'eqw': JobState.FAILED,  # Error states\n    'ehqw': JobState.FAILED,  # ..\n    'ehrqw': JobState.FAILED,  # ..\n    'd': JobState.COMPLETED,\n    'dr': JobState.COMPLETED,\n    'dt': JobState.COMPLETED,\n    'drt': JobState.COMPLETED,\n    'ds': JobState.COMPLETED,\n    'drs': JobState.COMPLETED,\n}\n\n\nclass GridEngineProvider(ClusterProvider, RepresentationMixin):\n    \"\"\"A provider for the Grid Engine scheduler.\n\n    Parameters\n    ----------\n    channel : Channel\n        Channel for accessing this provider. Possible channels include\n        :class:`~parsl.channels.LocalChannel` (the default),\n        :class:`~parsl.channels.SSHChannel`, or\n        :class:`~parsl.channels.SSHInteractiveLoginChannel`.\n    nodes_per_block : int\n        Nodes to provision per block.\n    min_blocks : int\n        Minimum number of blocks to maintain.\n    max_blocks : int\n        Maximum number of blocks to maintain.\n    parallelism : float\n        Ratio of provisioned task slots to active tasks. A parallelism value of 1 represents aggressive\n        scaling where as many resources as possible are used; parallelism close to 0 represents\n        the opposite situation in which as few resources as possible (i.e., min_blocks) are used.\n    walltime : str\n        Walltime requested per block in HH:MM:SS.\n    scheduler_options : str\n        String to prepend to the #$$ blocks in the submit script to the scheduler.\n    worker_init : str\n        Command to be run before starting a worker, such as 'module load Anaconda; source activate env'.\n    launcher : Launcher\n        Launcher for this provider. Possible launchers include\n        :class:`~parsl.launchers.SingleNodeLauncher` (the default),\n    \"\"\"\n\n    def __init__(self,\n                 channel=LocalChannel(),\n                 nodes_per_block=1,\n                 init_blocks=1,\n                 min_blocks=0,\n                 max_blocks=10,\n                 parallelism=1,\n                 walltime=\"00:10:00\",\n                 scheduler_options='',\n                 worker_init='',\n                 launcher=SingleNodeLauncher()):\n        label = 'grid_engine'\n        super().__init__(label,\n                         channel,\n                         nodes_per_block,\n                         init_blocks,\n                         min_blocks,\n                         max_blocks,\n                         parallelism,\n                         walltime,\n                         launcher)\n        self.scheduler_options = scheduler_options\n        self.worker_init = worker_init\n\n        if launcher in ['srun', 'srun_mpi']:\n            logger.warning(\"Use of {} launcher is usually appropriate for Slurm providers. \"\n                           \"Recommended options include 'single_node' or 'aprun'.\".format(launcher))\n\n    def get_configs(self, command, tasks_per_node):\n        \"\"\"Compose a dictionary with information for writing the submit script.\"\"\"\n\n        logger.debug(\"Requesting one block with {} nodes per block and {} tasks per node\".format(\n            self.nodes_per_block, tasks_per_node))\n\n        job_config = {}\n        job_config[\"submit_script_dir\"] = self.channel.script_dir\n        job_config[\"nodes\"] = self.nodes_per_block\n        job_config[\"walltime\"] = self.walltime\n        job_config[\"scheduler_options\"] = self.scheduler_options\n        job_config[\"worker_init\"] = self.worker_init\n        job_config[\"user_script\"] = command\n\n        job_config[\"user_script\"] = self.launcher(command,\n                                                  tasks_per_node,\n                                                  self.nodes_per_block)\n        return job_config\n\n    def submit(self, command, tasks_per_node, job_name=\"parsl.sge\"):\n        ''' The submit method takes the command string to be executed upon\n        instantiation of a resource most often to start a pilot (such as IPP engine\n        or even Swift-T engines).\n\n        Args :\n             - command (str) : The bash command string to be executed.\n             - tasks_per_node (int) : command invocations to be launched per node\n\n        KWargs:\n             - job_name (str) : Human friendly name to be assigned to the job request\n\n        Returns:\n             - A job identifier, this could be an integer, string etc\n\n        Raises:\n             - ExecutionProviderException or its subclasses\n        '''\n\n        # Set job name\n        job_name = \"{0}.{1}\".format(job_name, time.time())\n\n        # Set script path\n        script_path = \"{0}/{1}.submit\".format(self.script_dir, job_name)\n        script_path = os.path.abspath(script_path)\n\n        job_config = self.get_configs(command, tasks_per_node)\n\n        logger.debug(\"Writing submit script\")\n        self._write_submit_script(template_string, script_path, job_name, job_config)\n\n        channel_script_path = self.channel.push_file(script_path, self.channel.script_dir)\n        cmd = \"qsub -terse {0}\".format(channel_script_path)\n        retcode, stdout, stderr = self.execute_wait(cmd, 10)\n\n        if retcode == 0:\n            for line in stdout.split('\\n'):\n                job_id = line.strip()\n                if not job_id:\n                    continue\n                self.resources[job_id] = {'job_id': job_id, 'status': JobStatus(JobState.PENDING)}\n                return job_id\n        else:\n            print(\"[WARNING!!] Submission of command to scale_out failed\")\n            logger.error(\"Retcode:%s STDOUT:%s STDERR:%s\", retcode, stdout.strip(), stderr.strip())\n\n    def _status(self):\n        ''' Get the status of a list of jobs identified by the job identifiers\n        returned from the submit request.\n\n        Returns:\n             - A list of JobStatus objects corresponding to each job_id in the job_ids list.\n\n        Raises:\n             - ExecutionProviderException or its subclasses\n\n        '''\n\n        cmd = \"qstat\"\n\n        retcode, stdout, stderr = self.execute_wait(cmd)\n\n        # Execute_wait failed. Do no update\n        if retcode != 0:\n            return\n\n        jobs_missing = list(self.resources.keys())\n        for line in stdout.split('\\n'):\n            parts = line.split()\n            if parts and parts[0].lower().lower() != 'job-id' \\\n                    and not parts[0].startswith('----'):\n                job_id = parts[0]\n                status = translate_table.get(parts[4].lower(), JobState.UNKNOWN)\n                if job_id in self.resources:\n                    self.resources[job_id]['status'] = status\n                    jobs_missing.remove(job_id)\n\n        # Filling in missing blanks for jobs that might have gone missing\n        # we might lose some information about why the jobs failed.\n        for missing_job in jobs_missing:\n            self.resources[missing_job]['status'] = JobStatus(JobState.COMPLETED)\n\n    def cancel(self, job_ids):\n        ''' Cancels the resources identified by the job_ids provided by the user.\n\n        Args:\n             - job_ids (list): A list of job identifiers\n\n        Returns:\n             - A list of status from cancelling the job which can be True, False\n\n        Raises:\n             - ExecutionProviderException or its subclasses\n        '''\n\n        job_id_list = ' '.join(job_ids)\n        cmd = \"qdel {}\".format(job_id_list)\n        retcode, stdout, stderr = self.execute_wait(cmd, 3)\n\n        rets = None\n        if retcode == 0:\n            for jid in job_ids:\n                self.resources[jid]['status'] = JobStatus(JobState.COMPLETED)\n            rets = [True for i in job_ids]\n        else:\n            rets = [False for i in job_ids]\n\n        return rets\n", "path": "parsl/providers/grid_engine/grid_engine.py"}]}