changeset 817:d2c4c473e08e feature-world

Account synchronization more prudent
author HIROSE Yuuji <yuuji@gentei.org>
date Wed, 17 Jun 2020 13:54:01 +0900
parents ed2c8aab742d
children de988b0a7afa
files s4-funcs.sh s4-newworld.sh s4-world.sh
diffstat 3 files changed, 93 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/s4-funcs.sh	Wed Jun 17 08:16:59 2020 +0900
+++ b/s4-funcs.sh	Wed Jun 17 13:54:01 2020 +0900
@@ -1448,6 +1448,7 @@
   exit 0
 }
 dologin() {
+  test -n "$S4WORLD" && syncaccount
   checkauth
   st=$?
   if [ $st != 0 ]; then
--- a/s4-newworld.sh	Wed Jun 17 08:16:59 2020 +0900
+++ b/s4-newworld.sh	Wed Jun 17 13:54:01 2020 +0900
@@ -5,11 +5,6 @@
 #   $1 = World Display Name in UTF-8
 #   $2 = World ShortName in alpha-numeric
 #   $3 = World Description in UTF-8
-. `dirname $0`/s4-config.sh
-if ! type htmlescape >/dev/null 2>&1; then
-  . `dirname $0`/s4-funcs.sh ### > /dev/null 2>&1
-  trap 'exit 1' INT QUIT
-fi
 dispname=$1
 shortname=$2
 desc=$3
@@ -19,8 +14,7 @@
   read $1
 }
 
-echo db=$db URL=$URL isCGI=$isCGI
-if ! $isCGI; then
+if [ -z "$HTTP_HOST" ]; then
   while true; do
     dispname=`echo $dispname | tr -d ': \t\n"' | fold -w 28 | head -1`
     test -n "$dispname" && break
@@ -39,17 +33,30 @@
 fi
 echo "wl=$S4WORLDLIST"
 echo "$dispname:$shortname:$desc"
+# Create config
+DB=db/$shortname.sq3; export DB
+`dirname $0`/s4-init.sh
+. `dirname $0`/s4-config.sh
+if ! type htmlescape >/dev/null 2>&1; then
+  . `dirname $0`/s4-funcs.sh ### > /dev/null 2>&1
+  trap 'exit 1' INT QUIT
+fi
+
 newworld=$(
-  { echo "$S4WORLDLIST" | tr ' ' '\n' \
+  { echo $S4WORLDLIST | tr ' ' '\n' \
       | awk -F: "\$2 != \"$shortname\"{print}"
     echo "$dispname:$shortname:$desc"
-  } | tr '\n' ' ' | tr -d '"'
+  } | tr '\n' ' ' | sed 's/ $//' | tr -d '"'
 	)
 if [ -z "$newworld" ]; then
   exit
 fi
 
-# Create config
+masterdb=`(unset DB; . ./s4-config.sh; echo $DB)`
+S4MASTERDB=${masterdb:-db/cgi.sq3}
+echo Synching account: db=$db URL=$URL isCGI=$isCGI mas=$S4MASTERDB
+. ./s4-world.sh && syncaccount 'force'
+echo Synching done
 bgcolor=$(
   od -An -tu1 -N3 < /dev/urandom \
     | { read r g b
@@ -75,12 +82,9 @@
 # Update s4-config.sh
 cat<<-EOF | ed s4-config.sh
 	g/^S4WORLDLIST=/d
-	\$a
-	S4WORLDLIST="`echo $newworld`"
-	.
 	wq
 EOF
-DB=db/$shortname.sq3 `dirname $0`/s4-init.sh
-(S4MASTERDB=$db; db=db/$shortname.sq3; . ./s4-world.sh)
+echo "S4WORLDLIST=\"$newworld\"" >> s4-config.sh
+
 (cd `dirname $0`; ln -s s4$cgiext s4-world-$shortname$cgiext)
 echo $newworld added
--- a/s4-world.sh	Wed Jun 17 08:16:59 2020 +0900
+++ b/s4-world.sh	Wed Jun 17 13:54:01 2020 +0900
@@ -1,5 +1,7 @@
 #!/bin/sh
 
+autoremovestop=2
+
 # Setup variables for running time
 if $isCGI; then
   case "$S4WORLDLIST" in
@@ -53,48 +55,32 @@
   esac
 fi
 
-err "db=$db mas=$S4MASTERDB sessdb=$sessdb"
-# If in parent world, no need to do rest of jobs
-if [ -z "$S4MASTERDB" -o ! -s "$S4MASTERDB" ]; then
-  return
-fi
-# Confim child
-if [ "$db" -ef "$S4MASTERDB" ]; then
-  return		# Points to the same file
-fi
+
+syncaccount_1() {
 
-# Now Another world is ACTIVE
-# sessdb=`dirname $S4MASTERDB`/sess.sq3
-## skey="skey-`basename $mydir`"
-syncflag=${db%.*}.synctime
-runflag=${db%.*}.run
-userupdateflag=`dirname $S4MASTERDB`/`basename $userupdateflag`
-test ! -e "$userupdateflag"		&& return
-test "$syncflag" -nt "$userupdateflag"	&& return
-if [ -s "$runflag" ]; then
-  limit=`cat $runflag|tr -c -d 0-9`
-  if [ -n "$limit" -a "$limit" -gt `date +%s` ]; then
-    err "World $S4WORLD account sync withholded by process $$"
-    return		# Running sync by other process not leaching timeout
+  n_m=`query "SELECT printf('%d:%d',\
+  	      (SELECT count(*) FROM m.user), \
+	      (SELECT count(*) FROM user));"`
+  n=${n_m%:*}; m=${n_m#*:}		# n:m
+  if [ -z "$n" -o "$n" -lt 2 ]; then
+    err "Skipping account sync because m.user cannot be reached[n=$n]."
+    return -3
   fi
-fi
-echo $((`date +%s` + 10)) > $runflag	# Setting running flag by timeout 10s
+  if [ -z "$forceusersync" -a ! -f db/forceusersync ]; then
+    if [ $((m-n)) -le $((autoremovestop+0)) ]; then
+      # If if-condition evaluation fails, fall through to else-caluse
+      rm -f db/forceusersync
+    else
+      err "More than $autoremovestop users vanished($((m-n)))."
+      err "Automatic removal canceled.  If you want to sync user accounts"
+      err "forcibly, touch db/forceusersync file each time of world update."
+      return -4
+    fi
+  fi
+  err "`gdate +%S.%3N` Starting account synchronization[$$]"
 
-#  for sub.sq3
-# 
-#  main: user: 'taro', 'hanako', 'shige'
-#  sub:  user: 'taro', 'hanako', 'shige'
-#  sub2: user_s: ('taro', 't'), ('hanako', 'h'), ('shige', 's')
-#  then update
-# 
-
-## sqlite3 -cmd '.timer 1' -cmd '.echo 1' $db <<EOF
-err "`gdate +%S.%3N` Starting account synchronization[$$]"
-## cat > tmp/sql <<EOF
-num=$(sqlite3 -bail -cmd 'PRAGMA FOREIGN_KEYS=on' $db <<EOF
-.timeout 1000
-ATTACH DATABASE "$S4MASTERDB" AS m;
-CREATE TABLE IF NOT EXISTS user(name, primary key(name));
+##  num=$(sqlite3 -bail -cmd 'PRAGMA FOREIGN_KEYS=on' $db <<EOF
+  num=$(query <<EOF
 BEGIN;
 DElETE FROM main.user WHERE rowid NOT IN (SELECT rowid FROM m.user);
 INSERT INTO main.user(rowid, name)
@@ -124,15 +110,52 @@
 ), a_m AS (
   SELECT * FROM thisworld EXCEPT SELECT * FROM master
 ) SELECT (SELECT count(*) FROM m_a) + (SELECT count(*) FROM a_m);
-DETACH DATABASE m;
 EOF
-)
-### num=$(sqlite3 -bail -cmd 'PRAGMA FOREIGN_KEYS=on' $db < tmp/sql )
-if [ -n "$num" -a $num -eq 0 ]; then
-  err "`gdate +%S.%3N` Account synchronization[$$] done in difference $num"
-  echo "`date '+%F %T'`: Sync done by process $$" >> $syncflag
-else
-  err "Account synch[$$] failed or bailed with num=[$num]"
-fi
-test -e "$runflag" && rm -f "$runflag"
-return $num
+     )
+  if [ -n "$num" -a "$num" -eq 0 ]; then
+    err "`gdate +%S.%3N` Account synchronization[$$] done in difference $num"
+    echo "`date '+%F %T'`: Sync done by process $$" >> $syncflag
+  else
+    err "Account synch[$$] failed or bailed with num=[$num]"
+  fi
+  return $num
+}
+
+syncaccount() {
+  forceusersync=$1
+  err "db=$db mas=$S4MASTERDB sessdb=$sessdb"
+  # If in parent world, no need to do rest of jobs
+  if [ -z "$S4MASTERDB" -o ! -s "$S4MASTERDB" ]; then
+    return
+  fi
+  # Confim child
+  if [ "$db" -ef "$S4MASTERDB" ]; then
+    return		# Points to the same file
+  fi
+  # File based sync check precedes to DB count check for performance issue
+  syncflag=${db%.*}.synctime
+  runflag=${db%.*}.run
+  userupdateflag=`dirname $S4MASTERDB`/`basename $userupdateflag`
+  test ! -e "$userupdateflag"			&& return
+  [ -z "$forceusersync" -a "$syncflag" -nt "$userupdateflag" ] && return
+  if [ -s "$runflag" ]; then
+    limit=`cat $runflag|tr -c -d 0-9`
+    if [ -n "$limit" -a "$limit" -gt `date +%s` ]; then
+      err "World $S4WORLD account sync withholded by process $$"
+      return		# Running sync by other process not leaching timeout
+    fi
+  fi
+  echo $((`date +%s` + 10)) > $runflag	# Setting running flag by timeout 10s
+  query<<-EOF
+	.bail ON
+	ATTACH DATABASE "$S4MASTERDB" AS m;
+	EOF
+  syncaccount_1
+  rc=$?
+  test -e "$runflag" && rm -f "$runflag"
+  query<<-EOF
+	DETACH DATABASE m;
+	.bail OFF
+	EOF
+  return $rc
+}

yatex.org