[gnome-ostree] task: Don't use TaskDef to run tasks in different processes



commit 1a320b01dde9e45311c17f604aa9f786bf09591c
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Thu Jun 13 16:49:45 2013 -0400

    task: Don't use TaskDef to run tasks in different processes
    
    Before, we were using the TaskDef to represent both state in
    the parent runner process, and things in the child process. This
    got a bit confusing when understanding what code did what.
    
    Introduce a new TaskRunner that takes a TaskDef and runs it,
    splitting out the parent's state from the child's.
    
    For now, we still instantiate TaskDef objects in both the parent
    and the server, as it's the easiest way to share task metadata,
    but this will soon change.

 src/js/builtins/run_task.js |    2 +-
 src/js/task.js              |   86 ++++++++++++++++++++++++------------------
 2 files changed, 50 insertions(+), 38 deletions(-)
---
diff --git a/src/js/builtins/run_task.js b/src/js/builtins/run_task.js
index 3027836..552a20d 100644
--- a/src/js/builtins/run_task.js
+++ b/src/js/builtins/run_task.js
@@ -48,7 +48,7 @@ const RunTask = new Lang.Class({
        let taskset = Task.TaskSet.prototype.getInstance();
        let taskDef = taskset.getTask(args.taskName);
        let params = JSON.parse(args.parameters);
-       let instance = new taskDef(null, args.taskName, params);
+       let instance = new taskDef(args.taskName, params);
        instance.execute(cancellable);
     }
 });
diff --git a/src/js/task.js b/src/js/task.js
index 36aaff6..7f54dae 100644
--- a/src/js/task.js
+++ b/src/js/task.js
@@ -125,8 +125,7 @@ const TaskMaster = new Lang.Class({
 
     _pushTaskDefImmediate: function(taskDef, parameters) {
        let name = taskDef.prototype.TaskName;
-       let instance = new taskDef(this, name, parameters);
-       instance.onComplete = Lang.bind(this, this._onComplete, instance);
+       let instance = new taskDef(name, parameters);
        this._pendingTasksList.push(instance);
        this._queueRecalculate();
     },
@@ -198,8 +197,8 @@ const TaskMaster = new Lang.Class({
 
     isTaskExecuting: function(taskName) {
        for (let i = 0; i < this._executing.length; i++) {
-           let executingTask = this._executing[i];
-           if (executingTask.name == taskName)
+           let executingRunner = this._executing[i];
+           if (executingRunner.taskDef.name == taskName)
                return true;
        }
        return false;
@@ -248,28 +247,28 @@ const TaskMaster = new Lang.Class({
        this._reschedule();
     },
 
-    _onComplete: function(success, error, task) {
+    _onComplete: function(success, error, runner) {
        let idx = -1;
        for (let i = 0; i < this._executing.length; i++) {
-           let executingTask = this._executing[i];
-           if (executingTask !== task)
+           let executingRunner = this._executing[i];
+           if (executingRunner !== runner)
                continue;
            idx = i;
            break;
        }
        if (idx == -1)
-           throw new Error("TaskMaster: Internal error - Failed to find completed task:" + task.TaskName);
+           throw new Error("TaskMaster: Internal error - Failed to find completed task:" + 
runner.taskDef.name);
        this._executing.splice(idx, 1);
-       this.emit('task-complete', task, success, error);
+       this.emit('task-complete', runner, success, error);
        if (success && this._processAfter) {
            let changed = true;
-           let version = task.queryVersion();
+           let version = runner.taskDef.queryVersion();
            if (version !== null) {
-               let oldVersion = this._taskVersions[task.name];
+               let oldVersion = this._taskVersions[runner.taskDef.name];
                if (oldVersion == version)
                    changed = false;
                else if (oldVersion != null)
-                   print("task " + task.name + " new version: " + version);
+                   print("task " + runner.taskDef.name + " new version: " + version);
            }
            if (changed) {
                let tasksAfter = this._taskset.getTasksAfter(task.name);
@@ -293,9 +292,13 @@ const TaskMaster = new Lang.Class({
            if (version !== null) {
                this._taskVersions[task.name] = version;
            }
-           task._executeInSubprocessInternal(this.cancellable);
-           this._executing.push(task);
-           this.emit('task-executing', task);
+
+           let runner = new TaskRunner(this, task, Lang.bind(this, function(success, error) {
+               this._onComplete(success, error, runner);
+           }));
+           runner.executeInSubprocess(this.cancellable);
+           this._executing.push(runner);
+           this.emit('task-executing', runner);
        }
     }
 });
@@ -313,18 +316,11 @@ const TaskDef = new Lang.Class({
 
     DefaultParameters: {},
 
-    _VERSION_RE: /^(\d+\d\d\d\d)\.(\d+)$/,
-
-    _init: function(taskmaster, name, parameters) {
-       this.taskmaster = taskmaster;
+    _init: function(name, parameters) {
        this.name = name;
        this.parameters = Params.parse(parameters, this.DefaultParameters);
 
-       if (taskmaster !== null)
-           this.workdir = taskmaster.path.get_parent();
-       else
-           this.workdir = Gio.File.new_for_path(GLib.getenv('_OSTBUILD_WORKDIR'));
-
+       this.workdir = Gio.File.new_for_path(GLib.getenv('_OSTBUILD_WORKDIR'));
        BuildUtil.checkIsWorkDirectory(this.workdir);
 
        this.resultdir = this.workdir.get_child('results');
@@ -343,6 +339,30 @@ const TaskDef = new Lang.Class({
        return new JsonDB.JsonDB(path);
     },
 
+    queryVersion: function() {
+       return null;
+    },
+
+    execute: function(cancellable) {
+       throw new Error("Not implemented");
+    },
+});
+
+const TaskRunner = new Lang.Class({
+    Name: 'TaskRunner',
+
+    _VERSION_RE: /^(\d+\d\d\d\d)\.(\d+)$/,
+
+    _init: function(taskmaster, taskDef, onComplete) {
+       this.taskmaster = taskmaster;
+       this.taskDef = taskDef;
+       this.onComplete = onComplete;
+        this.name = taskDef.name;
+
+       this.workdir = taskmaster.path.get_parent();
+       BuildUtil.checkIsWorkDirectory(this.workdir);
+    },
+
     _loadVersionsFrom: function(dir, cancellable) {
        let e = dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, cancellable);
        let info;
@@ -367,14 +387,6 @@ const TaskDef = new Lang.Class({
        }
     },
 
-    queryVersion: function() {
-       return null;
-    },
-
-    execute: function(cancellable) {
-       throw new Error("Not implemented");
-    },
-
     _loadAllVersions: function(cancellable) {
        let allVersions = [];
 
@@ -397,7 +409,7 @@ const TaskDef = new Lang.Class({
        return allVersions;
     },
 
-    _executeInSubprocessInternal: function(cancellable) {
+    executeInSubprocess: function(cancellable) {
        this._cancellable = cancellable;
 
        this._startTimeMillis = GLib.get_monotonic_time() / 1000;
@@ -437,13 +449,13 @@ const TaskDef = new Lang.Class({
        GSystem.shutil_rm_rf(this._taskCwd, cancellable);
        GSystem.file_ensure_directory(this._taskCwd, true, cancellable);
 
-       let baseArgv = ['ostbuild', 'run-task', this.name, JSON.stringify(this.parameters)];
+       let baseArgv = ['ostbuild', 'run-task', this.name, JSON.stringify(this.taskDef.parameters)];
        let context = new GSystem.SubprocessContext({ argv: baseArgv });
        context.set_cwd(this._taskCwd.get_path());
        let childEnv = GLib.get_environ();
        childEnv.push('_OSTBUILD_WORKDIR=' + this.workdir.get_path());
        context.set_environment(childEnv);
-       if (this.PreserveStdout) {
+       if (this.taskDef.PreserveStdout) {
            let outPath = this._taskCwd.get_child('output.txt');
            context.set_stdout_file_path(outPath.get_path());
            context.set_stderr_disposition(GSystem.SubprocessStreamDisposition.STDERR_MERGE);
@@ -481,13 +493,13 @@ const TaskDef = new Lang.Class({
            target = this._failedDir.get_child(this._version);
            GSystem.file_rename(this._taskCwd, target, null);
            this._taskCwd = target;
-           this._cleanOldVersions(this._failedDir, this.RetainFailed, null);
+           this._cleanOldVersions(this._failedDir, this.taskDef.RetainFailed, null);
            this.onComplete(success, errmsg);
        } else {
            target = this._successDir.get_child(this._version);
            GSystem.file_rename(this._taskCwd, target, null);
            this._taskCwd = target;
-           this._cleanOldVersions(this._successDir, this.RetainSuccess, null);
+           this._cleanOldVersions(this._successDir, this.taskDef.RetainSuccess, null);
            this.onComplete(success, null);
        }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]