s4

view s4-world.sh @ 903:d81dd0ed2d6d

Add performance check logging.
author HIROSE Yuuji <yuuji@gentei.org>
date Sun, 03 Jan 2021 12:33:19 +0900
parents 3c9c65ff80f0
children 0352ff0fb37f
line source
1 #!/bin/sh
3 autoremovestop=2
5 # Setup variables for running time
6 if $isCGI; then
7 case "$S4WORLDLIST" in
8 *:*:*)
9 worldlistfile=cache/worldlist
10 worldgrpfile=cache/worldgrps
11 worldoptionfile=cache/worldoption
12 worldnamefile=cache/worldname
13 if [ ! -e $worldlistfile -o $worldlistfile -ot s4-config.sh \
14 -o ! -e $worldoptionfile -o $worldoptionfile -ot s4-config.sh \
15 -o s4-world.sh -nt $worldoptionfile ]
16 then
17 echo S4MASTERURL=$S4MASTERURL >> tmp/debug.out
18 cat <<-EOF > $worldlistfile
19 <div><table>
20 <tr><th>World List</th></tr>
21 <tr><td title="Base World$nl拠点となるWorldです">&rArr;
22 <a href="${S4MASTERURL:-$URL}">Base</a></td></tr>
23 EOF
24 true > $worldoptionfile
25 for i in $S4WORLDLIST; do
26 echo $i | {
27 IFS=: read name short d
28 cgi="s4-world-$short$cgiext"
29 conf="s4-config-$short.sh"
30 cat<<-EOF >>$worldlistfile
31 <tr><td title="$d">&rArr; <a href="$cgi">$name</a></td></tr>
32 EOF
33 cat<<-EOF >>$worldoptionfile
34 <option title="$d" value="$conf">$name</option>
35 EOF
36 echo "$name" > $worldnamefile.$short
37 }
38 done
39 if [ -s "$worldoptionfile" ]; then
40 echo "<option value=\"s4-config.sh\">Base</option>" >> $worldoptionfile
41 echo "</table>$nl</div>" >> $worldlistfile
42 sed 's/href="\([^>]*\)"/href="\1?grps"/' $worldlistfile \
43 > $worldgrpfile
44 else
45 true > $worldoptionfile; true > $worldlistfile # Remove contents
46 rm -f ${worldnamefile}.*
47 fi
48 fi
49 if [ -s "$worldlistfile" ]; then
50 S4WORLDS="▼spaste(\`$worldlistfile')"
51 S4WORLDNAME=${S4WORLD:+`cat $worldnamefile.$S4WORLD`}
52 S4WORLDGRPS="▼spaste(\`$worldgrpfile')"
53 fi
54 ;;
55 esac
56 fi
59 syncaccount_1() {
61 n_m=`query "SELECT printf('%d:%d',\
62 (SELECT count(*) FROM m.user), \
63 (SELECT count(*) FROM user));"`
64 n=${n_m%:*}; m=${n_m#*:} # n:m
65 if [ -z "$n" -o "$n" -lt 2 ]; then
66 err "Skipping account sync because m.user cannot be reached[n=$n]."
67 return -3
68 fi
69 if [ -z "$forceusersync" -a ! -f db/forceusersync ]; then
70 if [ $((m-n)) -le $((autoremovestop+0)) ]; then
71 # If if-condition evaluation fails, fall through to else-caluse
72 rm -f db/forceusersync
73 else
74 err "More than $autoremovestop users vanished($((m-n)))."
75 err "Automatic removal canceled. If you want to sync user accounts"
76 err "forcibly, touch db/forceusersync file each time of world update."
77 return -4
78 fi
79 fi
80 err "`gdate +%S.%3N` Starting account synchronization"
81 SYNC_M=1
83 prevsync=`tail -1 $syncflag|colrm 20` # 2020-06-21 12:30:00 = 19cols
84 syncall=${db%.*}.syncall
85 err syncallfile=$syncall
86 if [ -e $syncall ]; then
87 rm -f "$syncall"
88 err "Force update user_m for all users"
89 else
90 case "$prevsync" in
91 [2-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]\ [012][0-9]:??:??)
92 SYNCCOND="WHERE name in (SELECT name FROM m.user_s WHERE key='profupdate' AND val > '$prevsync')"
93 err "prevsync=$prevsync"
94 limited=`query "SELECT DISTINCT name FROM m.user_s $SYNCCOND;"`
95 if [ -n "$limited" ]; then
96 err synccond limited to "$limited"
97 else
98 err synccond canceled for user_m
99 SYNCCOND="WHERE NULL"
100 SYNC_M=
101 fi
102 err "Touch $syncall (owner=`id -un`) to update all user_m."
103 ;;
104 *)
105 echo arere ;;
106 esac
107 fi
108 ## num=$(sqlite3 -bail -cmd 'PRAGMA FOREIGN_KEYS=on' $db <<EOF
109 result=$(query <<EOF
110 BEGIN;
111 DElETE FROM main.user WHERE rowid NOT IN (SELECT rowid FROM m.user);
112 INSERT INTO main.user(rowid, name)
113 SELECT rowid, name FROM m.user
114 WHERE m.user.rowid NOT IN (SELECT rowid FROM user);
115 UPDATE user SET name = (SELECT name FROM m.user WHERE main.user.rowid=m.user.rowid);
116 DELETE FROM main.user_s WHERE rowid NOT IN (SELECT rowid FROM m.user_s);
117 REPLACE INTO main.user_s(rowid, name, key, type, val, bin)
118 SELECT rowid,* FROM m.user_s;
119 ${SYNC_M:+
120 DELETE FROM main.user_m WHERE rowid NOT IN (SELECT rowid FROM m.user_m);
121 REPLACE INTO main.user_m(rowid, name, key, type, val, bin)
122 SELECT rowid,* FROM m.user_m $SYNCCOND
123 EXCEPT
124 SELECT rowid,* FROM main.user_m $SYNCCOND
125 ;} /* SYNC_M closed here */
126 SELECT 'OK';
127 END;
128 EOF
129 )
130 err "`gdate +%S.%3N` Update account tables finished with result=[$result]"
131 test x"$result" = x"OK" && num=$(query <<EOF
132 /* Compare user tables */
133 WITH master AS (
134 SELECT p.rowid,* FROM m.user p
135 NATURAL LEFT JOIN m.user_s
136 ${SYNC_M:+ NATURAL LEFT JOIN m.user_m}
137 $SYNCCOND
138 ), thisworld AS (
139 SELECT p.rowid,* FROM user p
140 NATURAL LEFT JOIN user_s
141 ${SYNC_M:+ NATURAL LEFT JOIN user_m}
142 $SYNCCOND
143 ), m_a AS (
144 SELECT * FROM master EXCEPT SELECT * FROM thisworld
145 ), a_m AS (
146 SELECT * FROM thisworld EXCEPT SELECT * FROM master
147 ) SELECT (SELECT count(*) FROM m_a) + (SELECT count(*) FROM a_m);
148 EOF
149 )
150 if [ -n "$num" -a "$num" -eq 0 ]; then
151 err "`gdate +%S.%3N` Account synchronization done in difference $num"
152 echo "`date '+%F %T'`: Sync done by process $$" >> $syncflag
153 else
154 err "Account synch failed or bailed with num=[$num]"
155 fi
156 return $num
157 }
159 syncaccount() {
160 forceusersync=$1
161 ## err "db=$db mas=$S4MASTERDB sessdb=$sessdb"
162 # If in parent world, no need to do rest of jobs
163 if [ -z "$S4MASTERDB" -o ! -s "$S4MASTERDB" ]; then
164 return
165 fi
166 # Confim child
167 if [ "$db" -ef "$S4MASTERDB" ]; then
168 return # Points to the same file
169 fi
170 # File based sync check precedes to DB count check for performance issue
171 syncflag=${db%.*}.synctime
172 runflag=${db%.*}.run
173 userupdateflag=`dirname $S4MASTERDB`/`basename $userupdateflag`
174 test ! -e "$userupdateflag" && return
175 [ -z "$forceusersync" -a "$syncflag" -nt "$userupdateflag" ] && return
176 if [ -s "$runflag" ]; then
177 limit=`cat $runflag|tr -c -d 0-9`
178 err syncaccount: limit=$limit
179 if [ -n "$limit" -a "$limit" -gt `date +%s` ]; then
180 err "World $S4WORLD account sync withholded by process $$"
181 return # Running sync by other process not leaching timeout
182 fi
183 fi
184 echo $((`date +%s` + 10)) > $runflag # Setting running flag by timeout 10s
185 err syncaccount: setrunflag[$runflag]=`cat $runflag`
186 query<<-EOF
187 .bail ON
188 ATTACH DATABASE "$S4MASTERDB" AS m;
189 EOF
190 syncaccount_1
191 rc=$?
192 test -e "$runflag" && rm -f "$runflag"
193 query<<-EOF
194 DETACH DATABASE m;
195 .bail OFF
196 EOF
197 return $rc
198 }
200 getworldDB() { # $1=conf
201 (unset DB; . "$1"; echo ${DB:-$defaultdb})
202 }
204 worldnameDBlist() {
205 echo Base:Base:`getworldDB ./s4-config.sh`
206 for w in $S4WORLDLIST; do
207 case "$w" in
208 *:*:*:*) continue ;;
209 *:*:*) w=${w%:*}; name=${w%:*}; world=${w#*:} ;;
210 *) continue ;;
211 esac
212 d=`getworldDB "./s4-config-$world.sh"`
213 test -s "$d" && echo ${world}:${name}:$d
214 done
215 }
217 grepgrpworld() {
218 world=$1; wname=$2; exp=$3; tdb=$4
219 case $world in
220 Base) cgi=${S4MASTERURL:-$URL} ;;
221 *) cgi=s4-world-$world$cgiext ;;
222 esac
223 case $exp in
224 mem:*)
225 arg=${exp#*:}
226 cond="user = '$arg'"
227 guide="「${S4WORLDNAME:-Base}」以外の世界の所属グループ"
228 s="(<a href=\"$cgi?stage=grps&kwd=mem:$arg\">所属絞</a>)" ;;
229 *)
230 arg=`sqlquote "%$3%"`
231 cond="gname LIKE $arg"
232 guide="$exp を含むグループは別世界にもあります"
233 s="(<a href=\"$cgi?stage=grps&kwd=$exp\">絞込</a>)" ;;
234 esac
235 query <<-EOF |
236 ATTACH DATABASE "$tdb" AS td;
237 SELECT DISTINCT td.grp.rowid,hex(gname)
238 FROM td.grp NATURAL JOIN td.grp_mem
239 WHERE $cond;
240 DETACH DATABASE td;
241 EOF
242 while IFS='|' read rowid hgname; do
243 # echo rowid=$rowid - `echo "$hgname"|unhexize|htmlescape`
244 htmlgn=`echo $hgname|unhexize|htmlescape`
245 printf '<a href="%s?grp+%d">%s</a> ' "$cgi" "$rowid" "$htmlgn"
246 done | {
247 read ans
248 if [ -n "$ans" ]; then
249 w=`echo $wname|htmlescape`
250 u="<a href=\"$cgi?grps\"><span class=\"pre\">$w</span></a>"
251 cat<<-EOF
252 GUIDE:<h2>`echo "$guide"|htmlescape`</h2>
253 <tr>
254 <tr><td>$u $s</td>
255 <td>$ans</td>
256 </dl>
257 EOF
258 fi
259 }
260 }
262 peekgrpworlds() (
263 # $1=(Pattern|mem:User)
264 # err "pgw-1=[$1]"
265 for wd in `worldnameDBlist`; do
266 world=${wd%%:*}; wd=${wd#*:}
267 worldname=${wd%:*}
268 d=${wd#*:}
269 if [ ! $db -ef $d -a -s $d ]; then
270 grepgrpworld "$world" "$worldname" "$1" "$d"
271 fi
272 done | {
273 result=`cat`
274 if [ -n "$result" ]; then
275 cat<<-EOF
276 `echo "$result"|sed 's/^GUIDE://;2q'`
277 <table class="b">
278 `echo "$result"|grep -v '^GUIDE:'`
279 </table>
280 EOF
281 fi
282 }
283 )