[Fusionforge-commits] FusionForge branch feature/reactivity created. 6ea8e88af0b78dc17be7a09629b64e7a3dfd5db1

Sylvain Beucler beuc-inria at fusionforge.org
Wed Dec 10 18:18:31 CET 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".

The branch, feature/reactivity has been created
        at  6ea8e88af0b78dc17be7a09629b64e7a3dfd5db1 (commit)

- Log -----------------------------------------------------------------
commit 6ea8e88af0b78dc17be7a09629b64e7a3dfd5db1
Author: Sylvain Beucler <sylvain.beucler at inria.fr>
Date:   Wed Dec 10 18:18:12 2014 +0100

    reactivity: first POC

diff --git a/src/bin/light.php b/src/bin/light.php
new file mode 100644
index 0000000..165f91d
--- /dev/null
+++ b/src/bin/light.php
@@ -0,0 +1,117 @@
+#! /usr/bin/php -f
+<?php
+/**
+ * Small and fast system action trigger
+ *
+ * Copyright (C) 2014  Inria (Sylvain Beucler)
+ *
+ * This file is part of FusionForge. FusionForge is free software;
+ * you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the Licence, or (at your option)
+ * any later version.
+ *
+ * FusionForge is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FusionForge; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+//putenv('FUSIONFORGE_NO_PLUGINS=true');
+//putenv('FUSIONFORGE_NO_DB=true');
+
+require (dirname(__FILE__).'/../common/include/env.inc.php');
+require_once $gfcommon.'include/pre.php';
+require_once $gfcommon.'include/cron_utils.php';
+
+// (sysactionsq_lists) -> cf. mail_group_list
+// - sysaction_id references sysactions
+
+// (sysactionsq_membership)
+// -> user_groups_lastmodified
+
+
+// Locking: for a single script
+// flock() locks are automatically lost on program termination, however
+// that happened (clean, segfault...)
+$lock = null;  // global, or auto-closed by PHP and we lose the lock!
+function AcquireReplicationLock($script) {
+  // Script lock: http://perl.plover.com/yak/flock/samples/slide006.html
+  global $argv, $lock;
+  $lock = fopen($script, 'r') or die("Failed to ask lock.\n");
+
+  if (!flock($lock, LOCK_EX | LOCK_NB)) {
+    die("There's a lock for '$script', exiting\n");
+  }
+}
+
+// Invalidate users/groups cache e.g. when a user is added to a group
+// Special-case in 'publish-subscribe' mode
+function usergroups_sync() {
+		global $usergroups_lastsync;
+		$res = db_query_params("SELECT MAX(last_modified_date) AS lastmodified FROM nss_usergroups");
+		$row = db_fetch_array($res);
+		if ($row['lastmodified'] > $usergroups_lastsync) {
+				cron_reload_nscd();
+				$hook_params = array();
+				plugin_hook("usergroups_sync", $hook_params);
+				$usergroups_lastsync = time();
+		}
+}
+
+function sysaction_get_script($plugin_id, $sysaction_id) {
+		global $cron_arr;
+		if ($plugin_id == null) {
+				if (isset($cron_arr[$sysaction_id]))
+						return forge_get_config('source_path').'/cronjobs/'.$cron_arr[$sysaction_id];
+				else
+						return null;
+		} else {
+				// TODO
+				// $path = forge_get_config('plugins_path')."/$plugin/cronjobs/";
+		}
+}
+
+usergroups_sync();
+while (true) {
+		// Deal with pending requests
+		$res = db_query_params("SELECT * FROM sysactionsq WHERE status=$1", array('TODO'));
+		while ($arr = db_fetch_array($res)) {
+				usergroups_sync();
+				$script = sysaction_get_script($arr['plugin_id'], $arr['sysaction_id']);
+				if (!is_executable($script)) {
+						db_query_params("UPDATE sysactionsq SET status=$1, error_message=$2"
+										. " WHERE sysactionsq_id=$3",
+										array('ERROR',
+											  "Cron job {$arr['plugin_id']}/{$arr['sysaction_id']}"
+											  . " '$script' not found or not executable.\n",
+											  $arr['sysactionsq_id']));
+						continue;
+				}
+				db_query_params("UPDATE sysactionsq SET status=$1 WHERE sysactionsq_id=$2",
+								array('WIP', $arr['sysactionsq_id']));
+				AcquireReplicationLock($script);
+				$ret = null;
+				system("$script\n", $ret);
+				if ($ret == 0) {
+						db_query_params("UPDATE sysactionsq SET status=$1 WHERE sysactionsq_id=$2",
+										array('DONE', $arr['sysactionsq_id']));
+				} else {
+						db_query_params("UPDATE sysactionsq SET status=$1 WHERE sysactionsq_id=$2",
+										array('ERROR', $arr['sysactionsq_id']));
+				}
+		}
+
+		usergroups_sync();
+
+		sleep(1);
+}
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
diff --git a/src/common/include/SysActionQ.class.php b/src/common/include/SysActionQ.class.php
new file mode 100644
index 0000000..fc39000
--- /dev/null
+++ b/src/common/include/SysActionQ.class.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * FusionForge system action queue
+ *
+ * Copyright (C) 2014  Inria (Sylvain Beucler)
+ * http://fusionforge.org
+ *
+ * This file is part of FusionForge. FusionForge is free software;
+ * you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the Licence, or (at your option)
+ * any later version.
+ *
+ * FusionForge is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FusionForge; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+class SysActionQ extends Error {
+		function add() {
+				$res = db_query_params('INSERT INTO sysactionsq (
+				    plugin_id,
+				    sysaction_id,
+				    user_id,
+				    group_id,
+				    requested
+				  ) VALUES ($1, $2, $3, $4, now())',
+				  array(NULL, 1, NULL, 1));
+				if (!$res || db_affected_rows($res) < 1) {
+						$this->setError(sprintf(_('Error: Cannot create system action: %s'),
+												db_error()));
+						db_rollback();
+						return false;
+				}
+		}
+}
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
diff --git a/src/db/20141210-sysactionsq.sql b/src/db/20141210-sysactionsq.sql
new file mode 100644
index 0000000..6ea09fa
--- /dev/null
+++ b/src/db/20141210-sysactionsq.sql
@@ -0,0 +1,21 @@
+ALTER TABLE nss_usergroups ADD last_modified_date integer;
+CREATE TRIGGER nss_usergroups_update_last_modified_date
+    BEFORE INSERT OR UPDATE ON artifact
+    FOR EACH ROW
+    EXECUTE PROCEDURE update_last_modified_date();
+
+-- system queue
+CREATE TYPE sysactionsq_status AS ENUM ('TODO', 'WIP', 'DONE', 'ERROR');
+CREATE TABLE sysactionsq (
+    sysactionsq_id  SERIAL PRIMARY KEY,
+    plugin_id       integer REFERENCES plugins ON DELETE CASCADE,
+    sysaction_id    integer NOT NULL,
+    user_id         integer REFERENCES users ON DELETE CASCADE,
+    group_id        integer REFERENCES groups ON DELETE CASCADE,
+    status          sysactionsq_status DEFAULT 'TODO' NOT NULL,
+    error_message   text,
+    requested       timestamp,
+    started         timestamp,
+    stopped         timestamp
+);
+CREATE INDEX sysactionsq_status ON sysactionsq(status);
diff --git a/src/www/include/html.php b/src/www/include/html.php
index 2f26ea1..90a6c56 100644
--- a/src/www/include/html.php
+++ b/src/www/include/html.php
@@ -1002,6 +1002,10 @@ function site_user_header($params) {
 	$arr_l[] = '/account/';
 	$arr_attr[] = array('title' => _('Manage your account. Change your password, select your preferences.'));
 
+	$arr_t[] = _('System actions queue');
+	$arr_l[] = '/my/sysactionsq.php';
+	$arr_attr[] = array('title' => _('In-progress and past system replication'));
+
 	if (!forge_get_config('project_registration_restricted')
 			|| forge_check_global_perm('approve_projects', '')) {
 		$arr_t[] = _('Register Project');
diff --git a/src/www/my/sysactionsq.php b/src/www/my/sysactionsq.php
new file mode 100644
index 0000000..43c65d3
--- /dev/null
+++ b/src/www/my/sysactionsq.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * User's current and completed system actions
+ *
+ * Copyright (C) 2014  Inria (Sylvain Beucler)
+ * http://fusionforge.org
+ *
+ * This file is part of FusionForge. FusionForge is free software;
+ * you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the Licence, or (at your option)
+ * any later version.
+ *
+ * FusionForge is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FusionForge; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+require_once '../env.inc.php';
+require_once $gfcommon.'include/pre.php';
+require_once $gfcommon.'include/SysActionQ.class.php';
+
+global $HTML; // Layout object
+
+if (!session_loggedin()) {
+		exit_not_logged_in();
+}
+
+
+// Test
+if ($_SERVER['QUERY_STRING'] == 'create') {
+		$sa = new SysActionQ();
+		$sa->add();
+		if ($sa->isError()) {
+				exit_error($sa->getErrorMessage());
+		}
+}
+
+
+site_user_header(array('title' => _('System actions queue')));
+
+$u = session_get_user();
+$groups = $u->getGroups();
+$gids = array();
+foreach($groups as $g)
+		$gids[] = $g->getID();
+$gids = implode(',', $gids);
+
+$res = pg_query_params("SELECT * FROM sysactionsq WHERE user_id=$1 or group_id IN ($gids)"
+					   . " AND requested > NOW() - interval '1 day'",
+					   array($u->getID()));
+while($row = db_fetch_array($res)) {
+		print_r($row);
+		print "<br />";
+}
+
+site_user_footer();
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:

-----------------------------------------------------------------------


hooks/post-receive
-- 
FusionForge



More information about the Fusionforge-commits mailing list