[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