-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dbeaver/pro#2623 Timeout settings for tasks #32373
Conversation
git@github.com:dbeaver/dbeaver.git into dbeaver/pro#2795-editor-restore-path
Added service job implementation, ui settings, cancellation logic.
Handle database task status mechanics
Code cleanup
git@github.com:dbeaver/dbeaver.git into dbeaver/pro#2623-task-timeout-job
There are several cancelation cases supported: |
plugins/org.jkiss.dbeaver.registry/src/org/jkiss/dbeaver/registry/task/TaskManagerImpl.java
Outdated
Show resolved
Hide resolved
What if user put |
plugins/org.jkiss.dbeaver.registry/src/org/jkiss/dbeaver/registry/task/TaskManagerImpl.java
Outdated
Show resolved
Hide resolved
@@ -325,9 +328,33 @@ public DBTTaskRunStatus runTask(@NotNull DBRProgressMonitor monitor, @NotNull DB | |||
public TaskRunJob scheduleTask(@NotNull DBTTask task, @NotNull DBTTaskExecutionListener listener) { | |||
final TaskRunJob runJob = createJob((TaskImpl) task, listener); | |||
runJob.schedule(); | |||
if (serviceJob == null) { | |||
serviceJob = createServiceJob(); | |||
serviceJob.setSystem(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move it to job constructor
@Override | ||
protected IStatus run( | ||
IProgressMonitor monitor) { | ||
for (TaskRunJob taskJob : runningTasks) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Race condition may happen. Create copy of running tasks first and then iterate.
taskJob.setCancelByExecutionTime(); | ||
} | ||
} | ||
schedule(1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make 1000 a constant
protected IStatus run( | ||
IProgressMonitor monitor) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or rather
protected IStatus run( | |
IProgressMonitor monitor) { | |
protected IStatus run(IProgressMonitor monitor) { |
if (taskJob.checkCancelation()) { | ||
taskJob.setCancelByExecutionTime(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you delegating checks and cancellations to the callee? Do everything within one call in the job itself.
@@ -36,6 +36,9 @@ task_config_wizard_page_task_control_label_descr = Description | |||
task_config_wizard_page_task_text_label_task_id = Task ID | |||
task_config_wizard_page_task_create_folder_label = Task folder | |||
task_config_wizard_page_task_no_task_types_available = No suitable task types found for the current project.\nPlease create a new connection to continue. | |||
task_config_wizard_page_task_advanced_label = Advanced | |||
task_config_wizard_page_task_max_exec_time = Max execution time (in seconds): | |||
task_config_wizard_page_task_max_exec_time_descr = The time require to execute certain task, after it expired the task will be terminated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
task_config_wizard_page_task_max_exec_time_descr = The time require to execute certain task, after it expired the task will be terminated. | |
task_config_wizard_page_task_max_exec_time_descr = The timeout before the task will be terminated. |
public void widgetSelected( | ||
SelectionEvent e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public void widgetSelected( | |
SelectionEvent e) { | |
public void widgetSelected(SelectionEvent e) { |
Or rather use org.eclipse.swt.events.SelectionListener#widgetSelectedAdapter
if (maxExecutionTimeBtn.getSelection()) { | ||
task.setMaxExecutionTime(CommonUtils.toInt(maxExecutionTime.getText())); | ||
} else { | ||
task.setMaxExecutionTime(CommonUtils.toInt(0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
task.setMaxExecutionTime(CommonUtils.toInt(0)); | |
task.setMaxExecutionTime(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applied
@@ -430,6 +463,11 @@ public void saveSettings() { | |||
} | |||
TaskRegistry.getInstance().notifyTaskFoldersListeners(new DBTTaskFolderEvent(folder, DBTTaskFolderEvent.Action.TASK_FOLDER_REMOVE)); | |||
} | |||
if (maxExecutionTimeBtn.getSelection()) { | |||
task.setMaxExecutionTime(CommonUtils.toInt(maxExecutionTime.getText())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
task.setMaxExecutionTime(CommonUtils.toInt(maxExecutionTime.getText())); | |
task.setMaxExecutionTime(maxExecutionTime.getSelection()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applied
return runJob; | ||
} | ||
|
||
private Job createServiceJob() { | ||
return new Job("Service canceling job") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return new Job("Service canceling job") { | |
return new Job("Task canceling job") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applied
@@ -394,6 +421,7 @@ private void loadConfiguration() { | |||
String taskFolderName = JSONUtils.getString(taskJSON, TaskConstants.TAG_TASK_FOLDER); | |||
Date createTime = systemDateFormat.parse(JSONUtils.getString(taskJSON, TaskConstants.TAG_CREATE_TIME)); | |||
Date updateTime = systemDateFormat.parse(JSONUtils.getString(taskJSON, TaskConstants.TAG_UPDATE_TIME)); | |||
Integer maxExecutionTime = JSONUtils.getInteger(taskJSON, TaskConstants.TAG_MAX_EXEC_TIME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Integer maxExecutionTime = JSONUtils.getInteger(taskJSON, TaskConstants.TAG_MAX_EXEC_TIME); | |
int maxExecutionTime = JSONUtils.getInteger(taskJSON, TaskConstants.TAG_MAX_EXEC_TIME); |
@@ -545,6 +574,7 @@ private void serializeTasks(@NotNull JsonWriter jsonWriter) throws IOException { | |||
JSONUtils.field(jsonWriter, TaskConstants.TAG_CREATE_TIME, systemDateFormat.format(task.getCreateTime())); | |||
JSONUtils.field(jsonWriter, TaskConstants.TAG_UPDATE_TIME, systemDateFormat.format(task.getUpdateTime())); | |||
JSONUtils.serializeProperties(jsonWriter, TaskConstants.TAG_STATE, task.getProperties()); | |||
JSONUtils.field(jsonWriter, TaskConstants.TAG_MAX_EXEC_TIME, task.getMaxExecutionTime()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd not write this property if it's x <= 0
to avoid cluttering configuration files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applied
if (task.getMaxExecutionTime() > 0) { | ||
if ((System.currentTimeMillis() - taskStartTime) > (task.getMaxExecutionTime() * 1000)) { | ||
return true; | ||
} | ||
} | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (task.getMaxExecutionTime() > 0) { | |
if ((System.currentTimeMillis() - taskStartTime) > (task.getMaxExecutionTime() * 1000)) { | |
return true; | |
} | |
} | |
return false; | |
return task.getMaxExecutionTime() > 0 && System.currentTimeMillis() - taskStartTime > task.getMaxExecutionTime() * 1000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applied
Not working for tasks with scheduling |
serviceJob.schedule(); | ||
} | ||
try { | ||
job.join(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You changed core behavior.
We mustn't schedule new job here.
We mustn't call job.join() anywhere.
if (activeMonitor instanceof TaskLoggingProgressMonitor tlpm) { | ||
tlpm.setCanceled(true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not cancel any monitor?
if (error != null) { | ||
if (error instanceof DBException e) { | ||
throw e; | ||
} else { | ||
throw new DBException("Error executing task", error); | ||
} | ||
} | ||
runningTasks.remove(job); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't be executed if job fails with an error.
@@ -325,9 +335,13 @@ public DBTTaskRunStatus runTask(@NotNull DBRProgressMonitor monitor, @NotNull DB | |||
public TaskRunJob scheduleTask(@NotNull DBTTask task, @NotNull DBTTaskExecutionListener listener) { | |||
final TaskRunJob runJob = createJob((TaskImpl) task, listener); | |||
runJob.schedule(); | |||
if (serviceJob == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The runningTasks.add(job);
is missing here. Is this expected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The management of runningTasks
goes from job listener, method abouteToRun
…eaver/dbeaver.git into dbeaver/pro#2623-task-timeout-job
verified |
} | ||
if (taskStatus.getResultMessage() == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | |
if (taskStatus.getResultMessage() == null) { | |
} else if (taskStatus.getResultMessage() == null) { |
The new property "Max execution time" is specified for task automatic cancelation.
Handled and processed statuses.