ðŠ Chromeã¹ãããäžéã3â6âäºçŽå¶ã«ãããŸã§ã«3åééãã話
æå0ããå幎ã§Claude CodeèªåŸç°å¢ã建ãŠãä»ã¯æå120äžã«ãªããŸããããèªååã¯ã³ãŒããåããŠããæ¬çªã§å£ããŸãã
ãªããã®ä»çµã¿ãå¹ãã®ã
å人éçºã§èªååãæ¬æ Œçã«åãããšãå¿ ãã¶ã€ããåé¡ããããŸãããè€æ°ã®ãžã§ããåããªãœãŒã¹ãåæã«äœ¿ãããšããããšããåé¡ã§ãã
SNSèªååã®æèã§èšãã°ãChromeããã®ãªãœãŒã¹ã§ãããããã»ãã©ããŒã»æçš¿ã»note飿ºãªã©ããã©ãŠã¶ã䜿ããžã§ããæŒå€åããèµ°ããŸããç§ã®ç°å¢ã§ã¯ com.lily.autolike.ig-1 ãšãã launchd ãžã§ãã2æéããã«12å/æ¥ïŒ0:36ã2:36ã4:36âŠâŠ22:36ïŒèµ·åããChromeã䜿ã£ãŠèªåããããåããŸããããã ãã§ããã§ã«1æ¥12ããã»ã¹ã§ãããåçš®ã®ãžã§ããè€æ°ã¢ã«ãŠã³ãã»è€æ°SNSåååšããŸãã
äœãå¶åŸ¡ããªããã°ãèµ·åã¿ã€ãã³ã°ãéãªã£ããšã9åã®Chromeãåæã«ç«ã¡äžãããŸããMacãæ²é³Žãäžããã®ã¯æ³åã«é£ããããŸããã
åé¡ã¯ãå£ãæ¹ãã§ããã¡ã¢ãªäžè¶³ã§ã©ãããã¯ã©ãã·ã¥ãããªããŸã ãããããããå®éã«èµ·ããã®ã¯ãå šããã»ã¹ãçãããŸãŸæ¥µç«¯ã«é ããªããã¿ã€ã ã¢ãŠããå€çºãããšããçŸè±¡ã§ããåŠçã¯å®èµ°ããããã«èŠããã®ã«ãå®è³ªäœãããŠããªãããã°ã«ã¯ "TIMEOUT: killed after 900s" ã䞊ã³ãŸãã
ãã®åé¡ããåæèµ·åæ°ã®äžéã§å¶åŸ¡ããããšããçºæ³èªäœã¯æ£ããã§ããééããã®ã¯äžéå€ã®æ ¹æ ãšããžã§ãçš®å¥ã®åªå åºŠã®æ±ãã§ããã
~/.claude/scripts/browser-slot.sh ã¯ããã®3åã®ééããšä¿®æ£ãäžæ¬ã®ãã¡ã€ã«ã«å»ãŸããŠããŸããã³ã¡ã³ãã倿Žå±¥æŽä»£ããã«ãªã£ãŠããŠãæ°åãšæ¥ä»ã蟿ããšå€±æã®æ§é ãèŠããŸãã
åé¡ã®æ¬è³ªã¯ãçŽæçãªãªãœãŒã¹ç¯äººæ¢ãã
èªååãéããªããšãäœããé£ã£ãŠããã¯ãã ããšããçŽæãåããŸããChromeã¯ããã«ãéããã§ããç§ãäžéã3ã«èšå®ããã®ããChromeãã¡ã¢ãªãé£ã朰ããŠãããšãã仮説ã«åºã¥ããŠããŸããã
仮説ãééã£ãŠãããšã察çãééããŸããäžé3ã¯ãChromeãæããã°è»œããªãããšãã誀蚺ããçãŸããæ°åã§ããã宿ž¬ãããŸã§ããã®èª€èšºã1æ¥92åã®ã¹ããããçã¿åºããŠãããšæ°ã¥ããŸããã§ããã
éã«èšãã°ã宿ž¬ããŠã³ã¡ã³ãã«æ®ãããšã§ã誀蚺ãå¯èŠåãããŸããã¹ã¯ãªããã®ã³ã¡ã³ãïŒ5ã8è¡ç®ïŒã¯ãã®ãŸãŸäºåŸèª¿æ»ã¬ããŒãã«ãªã£ãŠããŸãã
# 宿ž¬(2026-08-09): Chromeç³»ãžã§ã9åã§åèš0.7GBãswapæ¯æžã®äž»ç¯ã¯ dasd(47GB)/
# ComfyUI(12GB)/iii(3.5GB)ã§ãã£ãŠãã©ãŠã¶ãžã§ãã§ã¯ãªãã£ããäžé3ã¯éå°ã«å³ãã
# 1æ¥ã§92åã®skip(å
šäœã®30%)ãåºããŠããã®ã§5ã«ç·©ããã
SLOT_MAX="${BROWSER_SLOT_MAX:-6}"
ã³ã¡ã³ãã«ã¯ã5ã«ç·©ããããšæžããŠãããŸãããå®éã® SLOT_MAX ã®ããã©ã«ãå€ã¯ 6 ã§ããã³ã¡ã³ããæžããæç¹ã§ã¯5ãæ³å®ããŠãããããã®ãŸãŸ6ã«èšå®ãããšããããšã§ãããã®ãã³ã¡ã³ããšå€ã®ãºã¬ãèªäœããäžæ°ã«ä¿®æ£ããçè·¡ã§ãã
ããã¯ãã¡ã€ã«æ¹åŒã¯ãååæ§ãã§çãã
ã»ããã©ã®ä»çµã¿ãšã㊠browser-slot.sh ãéžãã ã®ã¯ããã¡ã€ã«ã·ã¹ãã ã® mkdir ã¢ãããã¯æ§ã§ãã
GUARD_DIR="$SLOT_DIR/.guard"
acquire_guard() {
attempt=0
while [ "$attempt" -lt 100 ]; do
if mkdir "$GUARD_DIR" 2>/dev/null; then
printf '%s\n' "$$" > "$GUARD_DIR/pid"
GUARD_HELD=1
return 0
fi
# ...ãŸã³ãã¬ãŒãã®æé€...
attempt=$((attempt + 1))
sleep 0.05
done
return 1
}
mkdir ã¯POSIXäžã§ã¢ãããã¯ã§ãããã£ã¬ã¯ããªãååšããªããã°äœæããŠæåããã§ã«ååšããã°å€±æããããã®1ãã€ãã䜿ããªãæä»å¶åŸ¡ããè€æ°ãžã§ããåæã« acquire_guard() ãåŒãã§ãæ£ç¢ºã«1ã€ã ããéãä¿èšŒã«ãªããŸãã
ã¬ãŒããååŸããããã»ã¹ã¯ã~/.cache/lily-browser-slots/ 以äžã® *.lock ãã¡ã€ã«ãèµ°æ»ããŠçŸåšã®çšŒåæ°ãæ°ããŸããããã¯ãã¡ã€ã«ã®1è¡ç®ãPIDã§ãkill -0 $pid ã§çæ»ç¢ºèªããŸããæ»ãã§ããããã»ã¹ã®ããã¯ãã¡ã€ã«ã¯æé€ããŸãã
for lock in "$SLOT_DIR"/*.lock; do
[ -e "$lock" ] || continue
lock_pid="$(sed -n '1p' "$lock" 2>/dev/null)"
# ...
if ! kill -0 "$lock_pid" 2>/dev/null; then
rm -f "$lock"
continue
fi
running=$((running + 1))
çšŒåæ°ãäžéæªæºã§ããã°ãèªåã®ã©ãã«åã§ .lock ãã¡ã€ã«ãæžããŠã¬ãŒããè§£æŸããã³ãã³ããå®è¡ããŸããäžé以äžã§ããã°ã¹ããããåŸ
æ©ã§ãã
ãã®æ¹åŒã®å©ç¹ã¯ããã»ã¹ãç°åžžçµäºããŠãèªå·±ä¿®åŸ©ããããšã§ããã¯ã©ãã·ã¥ããããã»ã¹ã®ããã¯ãã¡ã€ã«ã¯æ¬¡ã®èª°ããæé€ããŸãã/tmp/ ã«æžããããã¡ã€ã«ã¯åèµ·åã§æ¶ãããflock ã®ããã«ã«ãŒãã«ãFD管çããããã§ããªããã·ã§ã«ã¹ã¯ãªãããæ±ãã«ã¯ããã®ããã¡ã€ã«ãäœã£ãŠæ»ãã ãæé€ãã®æ¹åŒãäžçªå
ç¢ã§ãã
ã¿ã€ã ã¢ãŠãã¯ã·ã§ã«ã«ä»»ããªã
å®è¡ã³ãã³ãã®ã¿ã€ã ã¢ãŠã㯠timeout ã³ãã³ãã§ã¯ãªãPerlãµãããã»ã¹ã§å¶åŸ¡ããŠããŸãïŒ277ã327è¡ç®ïŒãçç±ã¯ãtimeout ã³ãã³ããåããã»ã¹ã®ã¿ã殺ããŠã°ã©ã³ããã£ã€ã«ããæ®ãã±ãŒã¹ãããããã§ãã
Perlã® descendants() 颿°ã¯ /bin/ps -axo pid=,ppid= ã§å
šããã»ã¹ã®PID-PPID察å¿è¡šãäœããã«ãŒãããååž°çã«åå«ãåéããŸããã¿ã€ã ã¢ãŠãæã« SIGTERM â 1ç§åŸ
â SIGKILL ã®é ã§å
šåå«ã殺ããŸãã
local $SIG{ALRM} = sub { $timed_out = 1; stop_tree(); };
alarm $timeout;
ã¿ã€ã ã¢ãŠãããå Žåã®çµäºã³ãŒã㯠exit 124ãããã¯ã¹ã¯ãªããåŽã§æ€ç¥ããŠãã°ã« RESULT="timeout:${TIMEOUT_SEC}s" ãšããŠèšé²ãããŸãã
com.lily.autolike.ig-1.plist ã§ã¯ AUTOLIKE_TIMEOUT_SEC=3700ïŒçŽ61åïŒãç°å¢å€æ°ã§æž¡ããŠããŸãããbrowser-slot.sh ã® TIMEOUT_SEC ããã©ã«ãã¯900ç§ïŒ15åïŒã§ããåãžã§ãã BROWSER_SLOT_TIMEOUT_SEC ãäžæžãããªããã°ã15åã§KillãããŸãã
å šäœã®æµã
èªåããããžã§ã1æ¬ããChromeã1æ åããŠåŠçããŠè¿ããæµããå³ã§ç€ºããŸãã
launchd
com.lily.autolike.ig-1 âââ 0:36 / 2:36 / ... / 22:36ïŒ12å/æ¥ïŒ
â
â /bin/bash ~/dev/social-autolike/scripts/run-account.sh ig-1
âŒ
run-account.sh ig-1
â
â browser-slot.sh ig-1 --group engage --group-max N -- <chrome-cmd>
âŒ
browser-slot.sh
â
âââ acquire_guard()
â mkdir ~/.cache/lily-browser-slots/.guard â ã¢ãããã¯æä»
â
âââ¡ *.lock ãèµ°æ»ã㊠running ãæ°ãã
â æ»ãã PIDã®ããã¯ã¯æé€
â
ââ⢠å®å¹äžéãæ±ºãã
â reserved group (post)?
â YES â effective_max = SLOT_MAX (= 6)
â NO â effective_max = SLOT_MAX - SLOT_RESERVE_COUNT (= 5)
â
ââ⣠running >= effective_max ?
â YES + WAIT_SEC > 0 â 15ã45ç§ã©ã³ãã åŸ
æ©ããŠãªãã©ã€
â YES + åŸ
æ©éç â SKIP:global-limit ããã°ã«æžã㊠exit 0
â NO â .lock ãã¡ã€ã«ãæžããŠã¬ãŒãè§£æŸ
â
ââ†Perl supervisor ã§ <chrome-cmd> ãèµ·å
â alarm(TIMEOUT_SEC=900) â SIGALRM ã§ã¿ã€ã ã¢ãŠã
â åå«PIDãååž°åéã㊠SIGTERMâSIGKILL
â
ââ⥠cleanup()
.lock åé€
slot.log ãž result=exit:0 / timeout:900s çãèšé²
ã¹ãããååŸã¯ acquire_guard ã§ã®ã¿è¡ãããŸããè€æ°ãžã§ããåæã«åããŠããŠããã¬ãŒããåãã®ã¯1ããã»ã¹ãã€ã§ããçšŒåæ°ã®ã«ãŠã³ããš .lock ã®æžã蟌ã¿ãã¬ãŒãå
ã§å®çµããã®ã§ããã«ãŠã³ãããŠäžé以äžã ã£ãã®ã«ãå¥ããã»ã¹ãåæã«ééããŠäžéãè¶
ããããšããç«¶åã¯èµ·ããŸããã
ãã¡ã€ã«æ§æãšäž»èŠå€æ°
SLOT_DIR="${BROWSER_SLOT_DIR:-$HOME/.cache/lily-browser-slots}"
SLOT_MAX="${BROWSER_SLOT_MAX:-6}"
SLOT_RESERVED_GROUPS="${BROWSER_SLOT_RESERVED_GROUPS:-post}"
SLOT_RESERVE_COUNT="${BROWSER_SLOT_RESERVE:-1}"
TIMEOUT_SEC="${BROWSER_SLOT_TIMEOUT_SEC:-900}"
WAIT_SEC="${BROWSER_SLOT_WAIT_SEC:-600}"
SLOT_LOG="${BROWSER_SLOT_LOG:-$HOME/.cache/lily-browser-slots/slot.log}"
å
šå€æ°ãç°å¢å€æ°ã§ãªãŒããŒã©ã€ãå¯èœãªèšèšã§ããBROWSER_SLOT_MAX ãå€ããã°ã¹ã¯ãªãããäžåè§Šããã«äžéã倿Žã§ããŸããcom.lily.autolike.ig-1.plist ã AUTOLIKE_TIMEOUT_SEC=3700 ãæž¡ããŠããã®ãšåãæ¹åŒã§ãlaunchd ã® EnvironmentVariables ãããã¯ã§åãžã§ããç¬èªã®æåãæãŠãŸãã
ã¹ãããã©ãã«ã¯ã³ãã³ã第1åŒæ°ã§ãïŒäŸ: ig-1ïŒãããããã®ãŸãŸ ig-1.lock ãšãããã¡ã€ã«åã«ãªããåãã©ãã«ã®äºéèµ·å㯠SKIP: slot already held ã§é²ãããŸããlaunchd 㯠StartCalendarInterval ã§ãžã§ããèµ·åããŸãããååã®å®è¡ã60åè¶
ãã§çããŠãããšããŠããæ¬¡ã®èµ·åã§2ã€ç®ãèµ°ãããšã¯ãããŸããã
ã°ã«ãŒãå¶éã¯äžäœã®å¶åŸ¡ã§ãã--group engage --group-max 3 ãæž¡ãã°ãglobaläžéãšã¯å¥ã«ãengageã°ã«ãŒãã¯æå€§3ã€ãŸã§ããšããå¶éãéããããŸãããããã»ãã©ããŒã»noteãšã³ã²ãŒãžãåãã°ã«ãŒãã«å
¥ããŠããã°ãã¹ãããã¯ç©ºããŠããã®ã«engageã䞊走ããããç¶æ
ãé²ããŸãã
ãã°ã¯ slot.log ã«è¿œèšãããäžè¡ãã©ãŒãããã§ãã
2026-08-15T07:42:11+0900 label=xpilot.autopost group=post result=exit:0
2026-08-15T07:43:05+0900 label=ig-1 group=engage result=skip:global-limit:6/5:waited=600s
ãã®åœ¢åŒãéèšã®çŽ æã«ãªããŸããresult=skip:global-limit ã®è¡æ°ãæ°ããã°ããã®æ¥ã®ã¹ãããç«¶åãããããŸããresult=timeout:900s ãå¢ããŠãããã©ãããè©°ãŸã£ãŠãããµã€ã³ã§ãã
åŒã³åºãã®å®é
launchd ã® plist ãã run-account.sh ig-1 ãèµ·åãããšããã®ã¹ã¯ãªããå
ã§ browser-slot.sh ãåŒã³ãŸããåŒã³åºãã€ã¡ãŒãžã¯ããã§ãã
browser-slot.sh "ig-1" \
--group engage \
--group-max 3 \
-- python3 ~/dev/social-autolike/src/like.py ig-1
ig-1 ãã¹ãããã©ãã«ã§ããengage ã°ã«ãŒãã®æå€§3æ å¶éã®äžã«åãŸãã€ã€ãglobaläžéïŒengageã«ã¯å®å¹5æ ïŒã«ãåŒã£ãããã°åŸ
æ©ããŸããåŸ
æ©ã®æå€§æé㯠WAIT_SEC=600ïŒ10åïŒã§ããã®é15ã45ç§ã®ã©ã³ãã ééã§ãªãã©ã€ããŸããã©ã³ãã åããŠããã®ã¯ãè€æ°ãžã§ããåæã«ã¿ã€ã ã¢ãŠãããŠåæã«ãªãã©ã€ãå§ããå Žåã®åè¡çªãé¿ããããã§ãã
retry_delay=$((15 + RANDOM % 31))
600ç§åŸ ã£ãŠãæ ã空ããªããã°ãã¹ãããããŠexit 0ããŸããexit 0ãªã®ã¯launchdã«ãšã©ãŒãšããŠèšé²ãããªãããã§ããã¹ãããã¯ã倱æãã§ã¯ãªããä»åã¯èŠéã£ããã§ãããæ¬¡åã®èµ·åïŒ2æéåŸïŒã§èªç¶ã«ãªãã©ã€ãããŸãã
å®è£ ã®è©³çް
acquire_slot() ã®æ¥æïŒå®å¹äžéã®åå²
acquire_slot() ã®èã¯ãã°ããŒãã«äžéããã®ãŸãŸäœ¿ããªããšããã«ãããŸããã³ãŒãäžã§ãã£ãšãéèŠãªåå²ã¯177ã188è¡ç®ã§ãã
# äºçŽã°ã«ãŒãã¯SLOT_MAXãŸã§äœ¿ããããã以å€ã¯äºçŽåãå·®ãåŒããå®å¹äžéã§æ¢ããã
effective_max="$SLOT_MAX"
if ! is_reserved_group "$GROUP"; then
effective_max=$((SLOT_MAX - SLOT_RESERVE_COUNT))
[ "$effective_max" -lt 1 ] && effective_max=1
fi
if [ "$running" -ge "$effective_max" ]; then
SLOT_BLOCK_MESSAGE="SKIP: global limit reached ($running/$effective_max)"
SLOT_BLOCK_RESULT="skip:global-limit:$running/$effective_max"
SLOT_BLOCK_WAITABLE=1
release_guard
return 1
fi
is_reserved_group() 㯠SLOT_RESERVED_GROUPSïŒããã©ã«ã "post"ïŒã®ç©ºçœåºåããªã¹ããèµ°æ»ããŠãåŒæ°ã®ã°ã«ãŒãåãå«ãŸãããã確èªããŸãã
is_reserved_group() {
_needle="${1:-}"
[ -n "$_needle" ] || return 1
for _g in $SLOT_RESERVED_GROUPS; do
[ "$_g" = "$_needle" ] && return 0
done
return 1
}
ã¯ã©ãŒããããŠããªã $SLOT_RESERVED_GROUPS ã for ã§ãã®ãŸãŸå±éããŠããŸããã·ã§ã«ã®åèªåå²ãæå³çã«äœ¿ãæžãæ¹ã§ã"post engage" ã®ããã«ç©ºçœåºåãã§è€æ°ã°ã«ãŒããåæããããã° env 倿°ã«æžãå ããã ãã§ãã
å®å¹äžéã®èšç®ã¯åçŽã§ããSLOT_MAX=6ãSLOT_RESERVE_COUNT=1 ãªããengageã°ã«ãŒã㯠6 - 1 = 5 ãäžéã«ãªããŸããpostã°ã«ãŒãã ãã¯6ãŸã§äœ¿ããŸãããã®1æ ã®å·®ããengageã5æ¬èµ°ã£ãŠããŠãæçš¿ã¯å¿
ãå
¥ããããšããä¿èšŒãäœããŸãã
[ "$effective_max" -lt 1 ] && effective_max=1 ãšããã¬ãŒããéèŠã§ããSLOT_RESERVE_COUNT ã SLOT_MAX 以äžã«èšå®ããŠããŸã£ããšããå®å¹äžéã0以äžã«ãªã£ãŠå
šãžã§ããæ¢ãŸããšããäºæ
ãé²ããŸãã
ããã¯ãã¡ã€ã«ã®3è¡ãæå³ããããš
ã¹ãããã確ä¿ãããšãã©ãã«åã®ããã¯ãã¡ã€ã«ã«3è¡æžã蟌ã¿ãŸãïŒ198è¡ç®ïŒã
printf '%s\n%s\n%s\n' "$$" "$GROUP" "$(date +%s)" > "$LOCK_FILE"
1è¡ç®ãPIDã2è¡ç®ãã°ã«ãŒãåã3è¡ç®ãUNIXæå»ïŒãšããã¯ç§ïŒã§ãã
1è¡ç®ã®PIDã¯äºéã®åœ¹å²ãæã¡ãŸããäžã€ã¯çæ»ç¢ºèªã§ããããã¯ãã¡ã€ã«ãèµ°æ»ãããšããkill -0 "$lock_pid" 2>/dev/null ã§ããã»ã¹ãçããŠããã確ãããŸããæ»ãã§ããã°ããã¯ãã¡ã€ã«ãåé€ããŠæ¬¡ãžé²ã¿ãŸããããäžã€ã¯cleanupæã®èªå·±ç¢ºèªã§ããcleanup() ãèµ°ããšããsed -n '1p' ã§èªãã PIDãèªåã® $$ ãšäžèŽããã確èªããŠãããã¡ã€ã«ãåé€ããŸããå¥ããã»ã¹ã®ããã¯ãã¡ã€ã«ã誀ã£ãŠæ¶ãäºæ
ãé²ããŸãã
2è¡ç®ã®ã°ã«ãŒãåã¯ã°ã«ãŒãå¶éã«ãŠã³ãçšã§ããèµ°æ»äžã« lock_group="$(sed -n '2p' "$lock")" ã§èªã¿åºããèªåã®ã°ã«ãŒããšäžèŽããã° group_running ãã€ã³ã¯ãªã¡ã³ãããŸããããã¯ãã¡ã€ã«èªäœãã°ã«ãŒãæ
å ±ãæã£ãŠããã®ã§ã皌åäžããã»ã¹ã«ã¯ãšãªãæããå¿
èŠããããŸããã
3è¡ç®ã®ãšããã¯ç§ã¯ãããã°çšã§ãããã°ã ãèŠãŠãããã€èµ·åããã¹ããããããäžæãªãšããããã¯ãã¡ã€ã«ãçŽæ¥ cat ããã°èµ·åæå»ãããããŸãã
åŸ æ©ã«ãŒãã®ãã©ã³ãã ããå¹ãçç±
ã¹ãããååŸã«å€±æããåŸã®å詊è¡ã¯ãåºå®ééã§ã¯ãªãã©ã³ãã åŸ æ©ã䜿ããŸãïŒ269è¡ç®ïŒã
retry_delay=$((15 + RANDOM % 31))
15ã45ç§ã®ã©ã³ãã åŸ æ©ã§ãã
ãªãåºå®ã«ããªãããä»®ã«5ã€ã®engageãžã§ããåæã«ã¹ãããåŸ
ã¡ã«ãªã£ããšããŸããå
šå¡ãåºå®20ç§ã§å詊è¡ãããšã20ç§åŸã«5ã€åæã« acquire_guard() ãåŒã³ãŸããmkdir ã§ã¬ãŒããåããã®ã¯1ã€ã ãã§ãæ®ã4ã€ã¯åŒŸãããŠãŸã20ç§åŸ
ã¡ãŸãããããç¹°ãè¿ããããšãã¬ãŒãã®äºå¥ªæŠãåšæçã«çºçããŠã¹ã«ãŒããããèœã¡ãŸããã©ã³ãã åãããšå詊è¡ã¿ã€ãã³ã°ã忣ããé£ç¶ããŠæ ãåãŸã£ãŠããæµãã«ãªããŸããããµã³ããªã³ã°ããŒãããšåŒã°ããäžæå詊è¡ã®è¡çªãé¿ããå®çªã®ææ³ã§ãã
ããäžã€ãæ®ãåŸ æ©æéãšã®æ¯èŒãå ¥ã£ãŠããŸãïŒ271ã273è¡ç®ïŒã
remaining=$((WAIT_SEC - waited))
if [ "$retry_delay" -gt "$remaining" ]; then
retry_delay="$remaining"
fi
åŸ æ©ã¿ã€ã ã¢ãŠãæ®ã5ç§ã®ãšãã«ã30ç§åŸã«å詊è¡ããšããèšå®ã«ãªãããšãé²ããŸããæ®ãæéã®ãªã®ãªãŸã§æå¹ãªè©Šã¿ãç¶ããèšèšã§ãã
Perlãããã»ã¹ããªãŒãå šæ» ãããçç±
ã¿ã€ã ã¢ãŠãåŠçãã·ã§ã«ã® timeout ã³ãã³ãã«ä»»ããŠããªãçç±ã¯ãã°ã©ã³ããã£ã€ã«ãããã»ã¹ã®æ±ãã«ãããŸãã
Perlã¹ãŒããŒãã€ã¶ã® descendants() 颿°ïŒ287ã303è¡ç®ïŒã¯ /bin/ps -axo pid=,ppid= ã§ã·ã¹ãã å
šäœã®PID-PPID察å¿è¡šãäœããBFSã§æå®PIDã®å
šåå«ãåæããŸãã
sub descendants {
my ($root) = @_;
my %children;
open my $ps, "-|", "/bin/ps", "-axo", "pid=,ppid=" or return ();
while (my $line = <$ps>) {
next unless $line =~ /^\s*(\d+)\s+(\d+)\s*$/;
push @{$children{$2}}, $1;
}
close $ps;
my @queue = ($root);
my @found;
while (@queue) {
my $parent = shift @queue;
for my $pid (@{$children{$parent} || []}) {
push @found, $pid;
push @queue, $pid;
}
}
return @found;
}
ã¿ã€ã ã¢ãŠãæã«ã¯ stop_tree() ãåå«ãéé ïŒåâ芪ïŒã§ SIGTERM ããŠãã1ç§åŸ
æ©ãããŸã çããŠããããã»ã¹ã« SIGKILL ãéããŸãïŒ306ã312è¡ç®ïŒã
sub stop_tree {
return if $stopping++;
my @pids = descendants($child);
kill "TERM", reverse(@pids), $child;
select undef, undef, undef, 1;
kill "KILL", grep { kill 0, $_ } reverse(@pids), $child;
}
return if $stopping++ ã§ã¹ãçæ§ã確ä¿ããŠããŸããSIGALRMãšSIGTERMãåæã«å±ã㊠stop_tree() ãäºéåŒã³åºããããŠããæåã®1åã ãå®è¡ãããŸãã
Chromeã¯ã¬ã³ãã©ã»GPUã»ãããã¯ãŒã¯ãµãŒãã¹ãªã©å€æ°ã®åããã»ã¹ãç«ã¡äžããŸããã·ã§ã«ã® timeout ã³ãã³ãã¯çŽæ¥ã®åããã»ã¹ã«ããã·ã°ãã«ãéããªããããå«ä»¥äžã®ããã»ã¹ãæ®ããŸããæ®ã£ãChromeããã»ã¹ã次åèµ·åæã«ããã§ã«ChromeãåããŠãããç¶æ
ãäœãããã°ã€ã³ã»ãã·ã§ã³ãåããªããšããåé¡ãçºçããŠããŸãããPerlã§å
šåå«ããŸãšããŠæ®ºããŠããããã®ãŸã³ãChromeåé¡ã¯åºãªããªã£ãŠããŸãã
launchdã«ã¯ã¹ãããããšã©ãŒãšèŠããªã
ã¹ããããåããªãã£ãå Žåãã¹ã¯ãªãã㯠exit 0 ã§çµãããŸãïŒ257ã260è¡ç®ïŒã
if [ "$SLOT_BLOCK_WAITABLE" -ne 1 ] || [ "$WAIT_SEC" -eq 0 ]; then
echo "$SLOT_BLOCK_MESSAGE"
RESULT="$SLOT_BLOCK_RESULT"
exit 0
fi
com.lily.autolike.ig-1.plist 㯠StartCalendarInterval ã§åºå®æå»èµ·åïŒ0:36ã2:36âŠ22:36ïŒããŠããŸããlaunchdã¯çµäºã³ãŒãã0以å€ã ãšã倱æãããžã§ãããšããŠæ±ããå Žåã«ãã£ãŠã¯ ThrottleInterval ã®ããã«ãã£ã課ããŸãã
ã¹ãããã¯ãä»åã¯èŠéããã§ãã£ãŠå€±æã§ã¯ãããŸããã2æéåŸã®æ¬¡ã®èµ·åã¿ã€ãã³ã°ã§èªç¶ã«ãªãã©ã€ãããŸãããã°ã«ã¯ result=skip:global-limit ãšæžãããã®ã§äººéã«ã¯åºå¥ã§ããŸããlaunchdã«ã¯æ£åžžçµäºã«èŠããããã®äž¡ç«ã exit 0 ã®çç±ã§ãã
ç§ãè©°ãŸã£ã話
誀ç®1ïŒãChromeãéããã¯æã蟌ã¿ã ã£ã
æåã«ã¹ããã管çãäœã£ããšããäžéã3ã«èšå®ããŸãããæ ¹æ ã¯æèŠã§ããChromeã¯ããã«ãéããã ããåå以äžã«æãããããšãã倿ã§ããã
çç¶ã¯éãã«å§ãŸããŸãããèªåãããã®åŠçæ°ãæžã£ãŠãããããªæ°ãããããã°ãéèšãããš result=skip:global-limit ã1æ¥92ä»¶ãããå
šå®è¡æ°ã®çŽ30%ãã¹ãããååŸããããã«çµãã£ãŠããŸããã
ãã ãã¹ããããããŠãç¿åã§ã«ããŒã§ããã¯ãã ããšãã確蚌ãã€ã¢ã¹ããã£ãŠããã°ããæŸçœ®ããŠããŸããã2æéåŸã«ãŸã詊ã¿ããã倧äžå€«ããšã
確蚌ãã€ã¢ã¹ã厩ããã®ã¯ vm_stat ãš top ã§å®æž¬ãããšãã§ããçµæãã¹ã¯ãªããã®ã³ã¡ã³ãã«ãã®ãŸãŸæ®ã£ãŠããŸãã
# 宿ž¬(2026-08-09): Chromeç³»ãžã§ã9åã§åèš0.7GBãswapæ¯æžã®äž»ç¯ã¯ dasd(47GB)/
# ComfyUI(12GB)/iii(3.5GB)ã§ãã£ãŠãã©ãŠã¶ãžã§ãã§ã¯ãªãã£ããäžé3ã¯éå°ã«å³ãã
# 1æ¥ã§92åã®skip(å
šäœã®30%)ãåºããŠããã®ã§5ã«ç·©ããã
SLOT_MAX="${BROWSER_SLOT_MAX:-6}"
Chromeç³»ãžã§ã9åã®åèšã0.7GBã ã£ãã®ã«å¯ŸããdasdïŒAppleã®ãã°ããŒã¢ã³ïŒã47GBãComfyUIïŒç»åçæAIãµãŒããŒïŒã12GBã§ããChromeã®0.7GBã¯èª€å·®ã®ç¯å²ã§ãããChromeãç¯äººãšãã仮説ãå®å
šã«å€ããŠããã
ã³ã¡ã³ãã«ã¯ã5ã«ç·©ããããšæžããŠããã®ã«å€æ°ã®ããã©ã«ãå€ã¯ 6 ã§ãã宿ž¬ããŠã5ã§ååããšæã£ããã©6ã§ãããããšéäžã§èããå€ããã倿°ã ãçŽããŠã³ã¡ã³ããæžãããã®ãŸãŸæ®ããçè·¡ã§ãããããã§å€§äžå€«ãäžå®ãªä¿®æ£ãããããšãã人ã¯ã³ã¡ã³ããæžããªããé¡å·¡ããŸããã5ããšæžããåŸã«ã6ã§ããããªããšæãçŽããŠå€æ°ã ãå€ãããšããã®ãããçãŸããŸãã
ä¿®æ£ã®æ žå¿ã¯å€æ°èšèšã«ãããŸãããBROWSER_SLOT_MAX ãç°å¢å€æ°ã§ãªãŒããŒã©ã€ãã§ããèšèšã«ããŠãããããšã§ãã¹ã¯ãªãããäžåè§Šããã«äžé倿Žãã§ããŸãããlaunchdã®plistã« BROWSER_SLOT_MAX=5 ãäžè¡è¿œå ããã ãã§ããã¹ã¯ãªããå
ã«æ°åãããŒãã³ãŒãããŠãããã倿Žã®ãã³ã«ãã¡ã€ã«ãç·šéããŠãããã€ãçŽãå¿
èŠããããŸããã
誀ç®2ïŒäžéã6ã«æ»ããã®ã«æçš¿ã¬ãŒã³ã9åè©°ãŸã£ã
äžéãç·©åããŠãã6æ¥åŸã®2026-08-15ãæ°ããåé¡ãåºãŸããã
æã®ãã°ã確èªãããšãæçš¿ãžã§ãïŒxpilot.autopostïŒã® result=skip:global-limit:6/5 ã9ä»¶é£ç¶ã§äžŠãã§ããŸãããã¹ãããäžéã6ã®ã¯ããªã®ã«ã6/5ã§è©°ãŸã£ãããšããèšé²ã§ãæåã¯éèšãã°ããšæããŸããã
ã¹ã¯ãªããã®ã³ã¡ã³ãïŒ9ã14è¡ç®ïŒã«ãã®ãŸãŸèšé²ãæ®ã£ãŠããŸãã
# 2026-08-15: æã®7æ¬åætimeoutã§æ 6ãæ»ãã runã«å æãããæçš¿ã¬ãŒã³(xpilot.autopost
# ç)ã global-limit ã§9åskipãããããã/ãã©ããŒã¯1åèœã¡ãŠãç¿åã§åãè¿ãããã
# æçš¿ã¯ãã®æéåž¯ã®æ ãæ¶ãããšäºåºŠãšåãŸããªããããã§æçš¿çšã«æ ãäºçŽãã
# engageç³»(ããã/ãã©ããŒ/noteç)ã¯SLOT_MAXãã1ã€å°ãªãå®å¹äžéã§åããã
åå ã¯ããã§ããengageã°ã«ãŒãã®ãžã§ã7æ¬ãæã®æé垯ã«åæèµ·åããåããã»ã¹ã TIMEOUT_SEC=900ïŒ15åïŒã§è©°ãŸã£ãŠãããŸãããã¿ã€ã ã¢ãŠããããŸã§ã®15åéãã¹ãããã¯æ£åœã«å æãããŠããŸãã6æ ãå
šéšåãŸã£ãŠããç¶æ
ã§æçš¿ãžã§ããå
¥ãããšããããrunning=6 ã effective_max=6 以äžãªã®ã§åŒŸãããŸããããã9åç¹°ãè¿ãããŸããã
ããããã¯ç¿åã§åãè¿ããããæçš¿ã¯ãã®æéåž¯ã®æ ãæ¶ãããšäºåºŠãšåãŸããªãããšããç¹ãåé¡ã®æ žå¿ã§ãã
èªåãããã¯1æ¥12åã®èµ·åæ©äŒããããŸãã1åã¹ããããããŠãããŒã¿ã«ã®åŠçæ°ã¯å€§ããå€ãããŸããããããæçš¿ã¹ã±ãžã¥ãŒã«ã¯ãæ9æã«åºãããšããæå»æå®ã§ãããã®æ ãéãããã³ã³ãã³ãã¯ã1æ¥ãºã¬ãŠæçš¿ãããæ¬ çªãã«ãªããŸããç¹å®æéåž¯ã®æçš¿ã¯ãšã³ã²ãŒãžçã«çŽçµãããããã¹ãããã®ã³ã¹ããããããšã¯ãŸã£ããéããŸãã
çç¶ã¯åã skip:global-limit ã§ãããžã§ãã®çš®é¡ã«ãã£ãŠæ·±å»ããå
šãç°ãªããŸããã
ä¿®æ£: env倿°ã2æ¬è¿œå ããŠäºçŽæ ã®ä»çµã¿ãå
¥ããŸãããSLOT_RESERVED_GROUPS=postïŒäºçŽã°ã«ãŒãåïŒãš SLOT_RESERVE_COUNT=1ïŒäºçŽæ°ïŒãèšããengageã°ã«ãŒãã® effective_max = 6 - 1 = 5 ã«ããŸãããããã§ãengageã5æ¬èµ°ã£ãŠããŠããpostã¯å¿
ã6æ¬ç®ã«å
¥ããããä¿èšŒãããŸãã
ã¹ã¯ãªããã®å€æŽéã¯æå°ã§ããis_reserved_group() ãæ°èŠè¿œå ããacquire_slot() ã®äžéå€å®ã«4è¡ã®ãããã¯ãå·®ã蟌ãã ã ãã§ããåŒã³åºãåŽã®ã·ã§ã«ã¹ã¯ãªããã§ --group post ãæž¡ãããã«ããããplistã® EnvironmentVariables ãããã¯ã§ BROWSER_SLOT_RESERVED_GROUPS=post ãèšå®ããã°æå¹ã«ãªããŸãã
誀ç®3ïŒã¿ã€ã ã¢ãŠãå€ã®äºé管ç
com.lily.autolike.ig-1.plist ã«ã¯æ¬¡ã®ç°å¢å€æ°ãèšå®ãããŠããŸãã
<key>EnvironmentVariables</key>
<dict>
<key>AUTOLIKE_TIMEOUT_SEC</key>
<string>3700</string>
</dict>
AUTOLIKE_TIMEOUT_SEC=3700ïŒçŽ61åïŒã§ããäžæ¹ãbrowser-slot.sh ãPerlã¹ãŒããŒãã€ã¶ã®ã¿ã€ã ã¢ãŠãã«äœ¿ã倿°ã¯ BROWSER_SLOT_TIMEOUT_SEC ã§ãããã©ã«ãã¯900ç§ïŒ15åïŒã§ãã倿°åãéããŸãã
AUTOLIKE_TIMEOUT_SEC 㯠run-account.sh ãèªã倿°ã§ãPythonã¹ã¯ãªããåŽã®åŠçã¿ã€ã ã¢ãŠããå¶åŸ¡ããŠããŸããbrowser-slot.sh ã® TIMEOUT_SEC ã¯Perlã¹ãŒããŒãã€ã¶ã匷å¶çµäºãããŸã§ã®å¥ã¬ã€ã€ãŒã®ã¿ã€ã ã¢ãŠãã§ãã
ããã§è©°ãŸããŸãããPythonã¹ã¯ãªããããæå€§61åãããããšããããåæã§äœãããŠããã®ã«ãPerlã¹ãŒããŒãã€ã¶ãã15åã§åŒ·å¶çµäºãããèšå®ã®ãŸãŸã«ãªã£ãŠãããšã61å以å
ã«ã¯çµãããªãåŠçãã¿ã€ã ã¢ãŠãããŸããéã« BROWSER_SLOT_TIMEOUT_SEC ã®èšå®ãå¿ããŠããã©ã«ã900ç§ã§åãããšãæ¬æ¥å®èµ°ããã¯ãã®ã¢ã«ãŠã³ãæäœã15åã§æ®ºãããŸãããã®èšå®æŒããæ°ã¥ãã«ããã£ãçç±ã¯ãexit 124ã®ãã°ããã¿ã€ã ã¢ãŠãããšèšé²ãããã ãã§ããã¿ã€ã ã¢ãŠãäžéãå°ããããããšã¯æããŠãããªãããã§ãã
ãŸããplistã® Nice: 10 ãš LowPriorityIO: true ãšããèšå®ãé¢ä¿ããŠããŸãã
<key>LowPriorityIO</key>
<true/>
<key>Nice</key>
<integer>10</integer>
<key>ProcessType</key>
<string>Background</string>
Niceå€10ã¯CPUã¹ã±ãžã¥ãŒãªã³ã°ã®åªå 床ãäžããèšå®ã§ãlaunchdã¯ã·ã¹ãã ãè² è·é«ã®ãšãç©æ¥µçã«ãã®ãžã§ãã®åŠçãåŸåãã«ããŸããã·ã¹ãã ã®å®å®æ§ã®ããã«æ£ããèšå®ã§ããããäœåªå 床ãªã®ã§åŠçãé ããªããçµæãšããŠã¿ã€ã ã¢ãŠã900ç§ã«åœããããããªãããšããå¯äœçšããããŸããäœè£ãæã£ãã¿ã€ã ã¢ãŠãå€ãèšå®ããå¿ èŠãããçç±ã®äžã€ã§ãã
ä¿®æ£: run-account.sh ã®äžã§ AUTOLIKE_TIMEOUT_SEC ãèªã¿ãBROWSER_SLOT_TIMEOUT_SEC ãšã㊠browser-slot.sh ã«æž¡ã1è¡ã远å ããŸããããPythonã䜿ãã¿ã€ã ã¢ãŠãããšãPerlã¹ãŒããŒãã€ã¶ã䜿ãã¿ã€ã ã¢ãŠãããå¥å€æ°ãªã®ã¯ä»æ¹ãªããšããŠãåè
ããåŸè
ãžã®åãæž¡ããæç€ºçã«ã³ãŒãã«æžãããšã§ããèšå®ããã®ã«åæ ãããŠããªãããšããç¶æ
ããªãããŸãããenv倿°ã¯ã¿ã€ã ã¢ãŠãã«éãããã©ãã«æž¡ã£ãŠã©ãã§äœ¿ããããã®ã«ãŒãã远ãã«ãããã®ã§ããlaunchdã®plistã«æžããå€ãã©ã®ããã»ã¹ãŸã§å±ããŠãããããäžåºŠ printenv ã§ç¢ºèªããã®ã確å®ã§ãã
ã€ãŸãããã€ã³ã
p1ã»p2ã§èª€ç®1ã3ïŒChromeèª€èšºã»æçš¿ã¬ãŒã³è©°ãŸãã»ã¿ã€ã ã¢ãŠãäºé管çïŒã¯è©³ãã解説ããŸãããããã§ã¯ãã以å€ã®ãå®éã«èžãã 现ããèœãšã穎ãåæããŸãã
ã³ã¡ã³ããšå€æ°å€ã®ãºã¬ã¯ã倿Žéäžã®é¡å·¡ãã®çè·¡
ã¹ã¯ãªãã5ã8è¡ç®ã®ã³ã¡ã³ãã«ã¯ã5ã«ç·©ããããšæžããŠãããŸãããå®éã®å€æ°ã¯ SLOT_MAX="${BROWSER_SLOT_MAX:-6}" ã§ãã
# 宿ž¬(2026-08-09): Chromeç³»ãžã§ã9åã§åèš0.7GBãswapæ¯æžã®äž»ç¯ã¯ dasd(47GB)/
# ComfyUI(12GB)/iii(3.5GB)ã§ãã£ãŠãã©ãŠã¶ãžã§ãã§ã¯ãªãã£ããäžé3ã¯éå°ã«å³ãã
# 1æ¥ã§92åã®skip(å
šäœã®30%)ãåºããŠããã®ã§5ã«ç·©ããã
SLOT_MAX="${BROWSER_SLOT_MAX:-6}"
ããã¯ãã°ã§ã¯ãªãã5ãæžããåŸã§6ã§ããããšæãçŽãã倿°ã ãå€ããŠã³ã¡ã³ããæžãããã®ãŸãŸçœ®ãããçè·¡ã§ããå°ããª1è¡å€æŽã®ãšãã»ã©ã³ã¡ã³ããæŽæ°ãå¿ããŸããåŸããèªåã§ãã®ã³ã¡ã³ããèªãã§ã5ã®ã¯ãã6ã«ãªã£ãŠããããã°ãïŒããš5åãããã°ããŸããã倿°ãå€ãããšãã¯ã³ã¡ã³ããå ã«çŽãç¿æ £ãå¿ èŠã§ãã
Nice: 10 ãš LowPriorityIO: true ã®å¯äœçšãçãèŠã
plistã«ã¯ä»¥äžã®3ã€ãã»ããã§èšå®ãããŠããŸãã
<key>LowPriorityIO</key>
<true/>
<key>Nice</key>
<integer>10</integer>
<key>ProcessType</key>
<string>Background</string>
ã·ã¹ãã ãå§è¿«ããªãèšèšãšããŠæ£ããèšå®ã§ãããå¯äœçšããããŸããmacOSã¯dasdãComfyUIã®ãããªé«è² è·ããã»ã¹ãèµ°ã£ãŠãããšããNiceå€10ã®ãžã§ããç©æ¥µçã«åŸåãã«ããŸãããéåžž5ã8åã§çµããåŠçã12ã14åãããããšããç¶æ
ãçºçããTIMEOUT_SEC=900ïŒ15åïŒã®äœè£ãå®è³ª1ã3åãããªããªããŸããã¿ã€ã ã¢ãŠãå€ã¯Niceã«ããé
å»¶ãæã蟌ãã§äœè£ãæãããå¿
èŠããããŸãããèšå®ã¯åã£ãŠããã®ã«ã¿ã€ã ã¢ãŠããé »çºããããšããçç¶ã®åå ã¯ããã«ããããšãå€ãã§ãã
ãŸã³ãã¬ãŒãã®æé€ã¿ã€ãã³ã°ã«æå³ããã
acquire_guard() ã®å
éšã§ã¯ãã¬ãŒããã£ã¬ã¯ããªãååšããŠãPIDãã¡ã€ã«ã®äžèº«ãç¡å¹ãªå Žåãæé€ã attempt=20 以äžã«ãªããŸã§åŸ
ã¡ãŸãïŒã¹ã¯ãªãã110ã126è¡ç®ïŒã
case "$guard_pid" in
''|*[!0-9]*)
if [ "$attempt" -ge 20 ]; then
rm -f "$GUARD_DIR/pid"
rmdir "$GUARD_DIR" 2>/dev/null || true
fi
attempt=0ããå³åº§ã«æé€ããªãçç±ã¯ããmkdir ã§ã¬ãŒããååŸããŠãã printf '%s\n' "$$" > "$GUARD_DIR/pid" ã§æžã蟌ããŸã§ã®ããããªãŠã£ã³ããŠããä¿è·ããããã§ãããã®ééã«å¥ããã»ã¹ãèŠããšãPIDãã¡ã€ã«ã空ãŸãã¯ååšããªãç¶æ
ã«èŠããŸããçŽ1ç§ïŒ0.05ç§Ã20åïŒåŸ
ã£ãŠãããæ¬åœã«å€ç«ãããŸã³ãã¬ãŒãããšå€æããŸãããã®æå³ãç¥ããã«ããªãã¬ãŒããããåããªãã®ãããšãããã°ãå§ããŠ30åæº¶ãããŸããã
--group ãš --group-max ã®çæ¹ã ãæå®ã§exit 1
ã¹ã¯ãªããã®åŒæ°è§£æéšåïŒ233ã239è¡ç®ïŒã«ã¯æ¬¡ã®çžäºäŸåãã§ãã¯ããããŸãã
if [ -n "$GROUP" ] && [ -z "$GROUP_MAX" ]; then
echo "--group requires --group-max" >&2
exit 1
fi
if [ -z "$GROUP" ] && [ -n "$GROUP_MAX" ]; then
echo "--group-max requires --group" >&2
exit 1
fi
--group engage ã ãæžã㊠--group-max 3 ãå¿ãããšãã¹ã¯ãªãããexit 1ã§èœã¡ãŸããlaunchdã¯ããããšã©ãŒçµäºãšããŠèšé²ããThrottleInterval ã®ããã«ãã£ããããããšããããŸãããšã©ãŒã¡ãã»ãŒãžèªäœã¯æç¢ºã§ããã~/dev/social-autolike/logs/ig-1.launchd.log ã確èªãããŸã§æ°ã¥ããŸãããplistã® EnvironmentVariables ã§ BROWSER_SLOT_GROUP ã ãèšå®ã㊠BROWSER_SLOT_GROUP_MAX ãå¿ããå Žåãåãçç¶ã«ãªããŸãã
SLOT_RESERVE_COUNT >= SLOT_MAX ã§å®å¹äžéã1ã«ãªã
effective_max = SLOT_MAX - SLOT_RESERVE_COUNT ãšããèšç®ã§ãSLOT_RESERVE_COUNT ã誀ã£ãŠ SLOT_MAX 以äžã«èšå®ãããšå®å¹äžéã0以äžã«ãªããŸããã¹ã¯ãªããã«ã¯ [ "$effective_max" -lt 1 ] && effective_max=1 ãšãããã©ãŒã«ããã¯ãããã®ã§å®å
šã«ã¯æ¢ãŸããŸãããããengageã°ã«ãŒããå
šéš1æ å¶éã«ãªããç¶æ
ã«ãªããŸããã¹ããããæ¥å¢ããŸãããlaunchdã«ã¯exit 0ã§è¿ãã®ã§ãslot.log ãéèšããªããšçºèŠããŸãããSLOT_RESERVE_COUNT ã¯å¿
ã SLOT_MAX ããå°ããå€ã«èšå®ããŠãã ããã
ã¹ãããã©ãã«ã«äœ¿ããæåçš®ãéãããŠãã
ã¹ã¯ãªããã®åŒæ°æ€èšŒïŒ207ã209è¡ç®ïŒã§ãè±æ°åã»ãããã»ã¢ã³ããŒã¹ã³ã¢ã»ã³ãã³ã»ãã€ãã³ä»¥å€ãå«ãã©ãã«ã¯exit 1ã§èœã¡ãŸãã
case "$SLOT_LABEL" in
*[!A-Za-z0-9._:-]*) echo "invalid slot label: $SLOT_LABEL" >&2; exit 1 ;;
esac
ããã¯ãã¡ã€ã«åã $SLOT_LABEL.lock ã«ãªãããããã¡ã€ã«ã·ã¹ãã ã§åé¡ãèµ·ããæåã匟ãèšèšã§ãã@ig_account ã®ãããªã¢ããããŒã¯å
¥ãã®ã¢ã«ãŠã³ãèå¥åãçŽæ¥ã©ãã«ã«äœ¿ãããšããŠè©°ãŸããŸãããig-1 ã®ããã«ã·ã³ãã«ãªèå¥åã«å€æããŠããæž¡ãå¿
èŠããããŸãã
æã®ãåæ7æ¬ã¿ã€ã ã¢ãŠããã¯plistã®èšèšäžé¿ãã«ãã
com.lily.autolike.ig-1.plist ã® StartCalendarInterval ãèŠããšããã®ãžã§ãã¯æ¯æ¥6:36ïŒHour=6, Minute=36ïŒã«èµ·åããŸããè€æ°ã®engageãžã§ããåã Minute=36 ã«èšå®ãããŠãããšãlaunchdã¯åæã«èµ·åã詊ã¿ãŸããlaunchdã¯èµ·åé åºãä¿èšŒããŸããã
engageç³»ãžã§ã7æ¬ã6:36ã«äžæã«èµ·åããåããã»ã¹ã TIMEOUT_SEC=900 ã®äžéã«éãããŸã§ã¹ããããä¿æããå Žåã6:36ã7:51ã®75åéã6æ ããåããŠãããå®è³ªäœãããŠããªããããã»ã¹ã«å æãããŸããèµ·ååãåãžã§ãã§2ã5åãããèšèšå€æŽã§ã解決ã§ããŸãããplistãå
šéšæžãçŽãã³ã¹ãã«å¯ŸããŠãenv倿°2æ¬ïŒBROWSER_SLOT_RESERVED_GROUPS=post ãš BROWSER_SLOT_RESERVE=1ïŒã§æžãäºçŽæ ã®æ¹ãä¿®æ£ã³ã¹ããäœãã£ãã§ãã
exit 0ã¹ãããã¯ãã°éèšãªãã«éæã«ãªã
ã¹ããããåããªãã£ãå Žåã®ã¹ããã㯠exit 0 ã§çµäºããŸããlaunchdã®ãšã©ãŒãã°ã«ã¯äœãæ®ããŸãããslot.log ãéèšããªããã°ã仿¥äœä»¶ã¹ããããããããã¯ããããŸããã
æåã®1é±éãã¹ãããç30%ãçºçããŠããã®ã«ãlaunchdã«ãšã©ãŒããªãããæ£åžžããšæã£ãŠããŸãããæ¯æ grep 'result=skip' ~/.cache/lily-browser-slots/slot.log | wc -l ãèµ°ãããcronãåŸãã远å ããŸããããã¹ããã管çãå
¥ãã忥ããä»èŸŒãã§ããã¹ãã§ãããç£èŠãªãã®èªååã¯ãå£ããŠããã®ã«å£ããŠããªãããšæãããç¶æ
ãç¶ããŸãã
ãã¹ããã©ã¯ãã£ã¹
å®è£ ãšå€±æããèžçãããåçš®ã®ã»ããã©æ©æ§ãäœããšãã®æéãåæããŸãã
1. å šå€æ°ãç°å¢å€æ°ã§ãªãŒããŒã©ã€ãã§ãã圢ã«ãã
SLOT_MAX="${BROWSER_SLOT_MAX:-6}" ã®åœ¢ã§æžããŠãããšãã¹ã¯ãªãããäžåè§Šããã« launchd ã® EnvironmentVariables ãããã¯ããæåã倿Žã§ããŸããäžéãå€ãããã³ã«ãã¡ã€ã«ãç·šéããŠã³ããŒãçŽãå¿
èŠããªããªããŸããããã®ç°å¢ã ãäžé3ã«ãããããç¹å®ã®ãžã§ãã ãã¿ã€ã ã¢ãŠããé·ããããããšããèŠä»¶ã«æè»ã«å¯Ÿå¿ã§ããŸããBROWSER_SLOT_MAX BROWSER_SLOT_TIMEOUT_SEC BROWSER_SLOT_RESERVED_GROUPS BROWSER_SLOT_RESERVE ã®4倿°ãæã£ãŠããã°ãã¹ã¯ãªããæ¬äœã¯å€æŽãŒãã§ç°å¢ããšã®èª¿æŽãå®çµããŸãã
2. ã¹ãããã¯exit 0ã§launchdã«ãšã©ãŒãšèŠããªã
ãä»åã¯èŠéã£ããã¯ãžã§ãã®å€±æã§ã¯ãããŸãããlaunchdã¯éãŒãã®exitã³ãŒãã倱æãšããŠèšé²ããThrottleInterval ã®ããã«ãã£ããããããšããããŸããã¹ãããã¯exit 0ã§çµäºãã人éåãã®èšé²ã¯ slot.log ã«æ®ãèšèšã«ããŠãã ããããlaunchdã«ã¯æ£åžžçµäºããslot.logã«ã¯è©³çްããšããäºå±€ã®èšé²ãå¿
èŠã§ãã
3. ã³ã¡ã³ãã«ã¯ã宿ž¬ããæ¥ä»ãšå ·äœçãªæ°å€ããæžã
# 宿ž¬(2026-08-09): Chromeç³»ãžã§ã9åã§åèš0.7GBãswapæ¯æžã®äž»ç¯ã¯ dasd(47GB)/ComfyUI(12GB)
SLOT_MAX="${BROWSER_SLOT_MAX:-6}"
倿°ã®ãã°ã«å®æž¬å€ãšæ¥ä»ãæžããŠãããšãããªããã®æ°åãããåŸãã远ããŸããã³ã¡ã³ãã倿Žå±¥æŽã®ä»£ããã«ãªããæ¬¡ã®å®æž¬ã§æŽæ°ããåæ©ã«ããªããŸãããæèŠã§æ±ºããæ°åãã«ã¯æŽæ°åºæºããããŸããããã宿ž¬ã§æ±ºããæ°åãã«ã¯ã次ã«å®æž¬ããŠãã®å€ãè¶ ããã倿Žããããšããæ¡ä»¶ãèªåçã«ä»ããŸãã
4. ã¿ã€ã ã¢ãŠãã®ã¬ã€ã€ãŒã倿°åã§æç€ºçã«åé¢ãã
ã¢ããªåŽã®ã¿ã€ã ã¢ãŠãïŒAUTOLIKE_TIMEOUT_SECïŒãšPerlã¹ãŒããŒãã€ã¶ã®ã¿ã€ã ã¢ãŠãïŒBROWSER_SLOT_TIMEOUT_SECïŒã¯åœ¹å²ãéããŸããäž¡è
ãæç€ºçã«æ¥ç¶ããã³ãŒãã run-account.sh ã«æžããŠããå¿
èŠããããŸãã
export BROWSER_SLOT_TIMEOUT_SEC="${AUTOLIKE_TIMEOUT_SEC:-900}"
ãã®1è¡ããªããšãplistã«3700ãšèšå®ããã®ã«Perlã900ç§ã§Killããããšããç¶æ
ãç¶ããŸãã倿°ã®åãæž¡ãã¯ãã©ãã«æžããå€ãã©ã®ããã»ã¹ãŸã§å±ãããã printenv ã§äžåºŠç¢ºèªããã®ã確å®ã§ãã
5. ã°ã«ãŒãå¶éãšã°ããŒãã«å¶éã®äºæ®µæ§ãã«ãã
ã°ããŒãã«äžéïŒSLOT_MAX=6ïŒã ãã§ã¯å¶åŸ¡ãç²ããªããŸãã--group engage --group-max 3 ãæž¡ããšãengageã¯ã°ããŒãã«äžé以äžã§ã3æ¬ãŸã§ããšãã现ç²åºŠã®å¶åŸ¡ãã§ããŸããåçš®ãžã§ããéå°äžŠèµ°ããŠã¬ãŒãå¶éã«åœããã®ãé²ããããšãã«æå¹ã§ããã°ã«ãŒãå¶éã¯ã°ããŒãã«å¶éãšç¬ç«ããŠè©äŸ¡ãããã®ã§ããengageã2æ¬ã»noteã1æ¬ã»åèš3æ¬ãã°ããŒãã«äžé6ã¯äœã£ãŠããããšããç¶æ
ã§åå¥ã®ã°ã«ãŒãå¶éã ãå
ã«çºåããèšèšã«ã§ããŸãã
6. äºçŽæ ã¯ãéã¿ãéããžã§ããæ··åšãããšããã ãå ¥ãã
SLOT_RESERVED_GROUPS=post ãš SLOT_RESERVE_COUNT=1 ã§postã°ã«ãŒãå°çšæ ã1ã€ç¢ºä¿ããŸãããç¿æ¥ãªã«ããªã§ãããããããšããã®æéåž¯ãæ¶ãããšäºåºŠãšåãŸããªãæçš¿ããååã«æ±ããšãæçš¿ãé£ç¶ã¹ããããããŸãããžã§ãã®éã¿ãåäžãªå Žåã¯äºçŽæ ãå
¥ãããšèšå®ãè€éã«ãªãã ãã§ãããã¹ãããããããšå°ããžã§ããšãã¹ããããããŠã次åã§ã«ããŒã§ãããžã§ããæ··åšãããšããã ãå°å
¥ããŠãã ããã
7. åŸ æ©ééãã©ã³ãã ã«ããŠãµã³ããªã³ã°ããŒããé¿ãã
retry_delay=$((15 + RANDOM % 31))
åºå®ééã§å詊è¡ãããšãè€æ°ã®ãžã§ããåæã«åŸ
æ©äžã«ãªã£ããšããå
šå¡ãåãã¿ã€ãã³ã°ã§ã¬ãŒãã奪ãåããŸããmkdir ã§ã¬ãŒããåããã®ã¯1ããã»ã¹ã ããªã®ã§ãæ®ãã¯åŒŸãããŠãŸãåºå®ééåŸã«å詊è¡ããŸãããã®è¡çªãåšæçã«ç¹°ãè¿ãããŠã¹ã«ãŒããããèœã¡ãŸãã15ã45ç§ã®ã©ã³ãã åã§å詊è¡ã¿ã€ãã³ã°ã忣ããã¹ããããé æ¬¡åãŸã£ãŠããæµãã«ãªããŸãã
8. æ®ãåŸ æ©æéãšã®æ¯èŒãå¿ ãå ¥ãã
remaining=$((WAIT_SEC - waited))
if [ "$retry_delay" -gt "$remaining" ]; then
retry_delay="$remaining"
fi
åŸ æ©ã¿ã€ã ã¢ãŠãæ®ã5ç§ã®ãšãã«ã30ç§åŸã«å詊è¡ããšããèšå®ã«ãªãããšãé²ããŸãããã®æ¯èŒããªããã°ãæ®ãæéãŒãã§ããã1å詊ã¿ã䟡å€ããã£ããæ©äŒãéããŸãã
9. ããã»ã¹ããªãŒããŸãããšæ®ºãã«ã¯PerlãPythonãå¿ èŠ
ã·ã§ã«ã® timeout ã³ãã³ãã¯çŽæ¥ã®åããã»ã¹ã«ããã·ã°ãã«ãéããŸãããChromeã¯ã¬ã³ãã©ããã»ã¹ãGPUããã»ã¹ãªã©å€æ°ã®åå«ããã»ã¹ãç«ã¡äžããŸããtimeout ã§èŠªã ãæ®ºããŠãå«ä»¥äžãæ®ãããæ¬¡åèµ·åæã«Chromeããã§ã«åããŠããããšããç¶æ
ãç¶ããŸããPerlã® descendants() 颿°ã®ããã« /bin/ps -axo pid=,ppid= ã§PID-PPID察å¿è¡šãäœããBFSã§å
šåå«ãåæããŠSIGTERMâSIGKILLãéãå®è£
ãå¿
èŠã§ããPerlãéžã¶çç±ã¯ãmacOSã«æšæºã§å
¥ã£ãŠããããã§ãã
10. ããã¯ãã¡ã€ã«ã«PIDã»ã°ã«ãŒãåã»ãšããã¯ç§ã®3è¡ãæžã
printf '%s\n%s\n%s\n' "$$" "$GROUP" "$(date +%s)" > "$LOCK_FILE"
1è¡ç®ã®PIDã§ kill -0 ã«ããçæ»ç¢ºèªãã§ããŸãã2è¡ç®ã®ã°ã«ãŒãåã§ã°ã«ãŒãå¶éã®ã«ãŠã³ããã§ããŸãã3è¡ç®ã®ãšããã¯ç§ã§ããã€èµ·åããã¹ãããããããããã°ã§ããŸããããã¯ãã¡ã€ã«ã cat ããã ãã§ããã®ã¹ãããã®ç¶æ
ãå
šéšããããŸããã°ã«ãŒãæ
å ±ãããã¯ãã¡ã€ã«ã«æãããããšã§ã皌åäžã®ä»ããã»ã¹ã«ã¯ãšãªãæããå¿
èŠããªããªããŸãã
11. ãŸã³ãã¬ãŒãã®ã¯ãªãŒã³ã¢ãããå¿ ãå ¥ãã
ã¬ãŒããååŸããããã»ã¹ãç°åžžçµäºãããšãã¬ãŒããã£ã¬ã¯ããªãæ®ãç¶ããŸããæ¬¡ã®ããã»ã¹ãã¬ãŒããåããªããªããå
šã¹ããã管çãæ¢ãŸããŸããã¬ãŒãã®PIDã kill -0 ã§ç¢ºèªããæ»ãã§ããã° rmdir ã§æé€ããããžãã¯ããªããã°ãã1ããã»ã¹ãã¯ã©ãã·ã¥ããç¬éã«å
šãžã§ããè©°ãŸãããšããèé害æ§ãŒãã®å®è£
ã«ãªããŸããã¬ãŒãã®ã¯ãªãŒã³ã¢ããã¯èªå·±ä¿®åŸ©ã®æéèŠéšåã§ãã
12. slot.log ã®éèšãèªååã®åæ¥ããå
¥ãã
# cronã§æ¯æå®è¡
skip_count=$(grep "result=skip:global-limit" ~/.cache/lily-browser-slots/slot.log | wc -l)
echo "today skip:global-limit count = $skip_count"
launchdã®ãã°ã ãèŠãŠãããšãå
šéšexit 0ã§æ£åžžãã«èŠããŸããã¹ããã管çã®ã¹ãããç㯠slot.log ã®éèšã§ããããããŸãããã1æ¥92ä»¶ã®ã¹ããããçºçããŠããã®ã«1é±éæ°ã¥ããªãã£ãããšããäºæ
ãé²ãã«ã¯ãæåããéèšãèªååããŠãã ãããã¹ãããçã15%ãè¶
ãããäžéãäºçŽæ ã®èŠçŽããµã€ã³ã§ãã
13. èµ·ååããžã§ãéã§æ°åãã€ããã
StartCalendarInterval ã§è€æ°ãžã§ãã® Minute ãåãå€ã«ãªããšãlaunchdãåæèµ·åããŸããåæèµ·åãããžã§ããã¿ã€ã ã¢ãŠãã¬ãŒã¹ã«å
¥ããšãã¹ããã6æ ãé·æéå æãããŸããåãžã§ãã® Minute ã2ã5åãã€ãããã ãã§ãã¹ãããã®äºå¥ªãèªç¶ã«åæ£ããŸããäºçŽæ ãšçµã¿åããããšæçš¿ã¬ãŒã³ã®è©°ãŸããããã«æžããŸããplistã®ãšã³ããªãå€ãå Žåã¯äžæ¬æžãæãã®ã³ã¹ãããããŸãããæ°èŠãžã§ãã远å ãããã³ã«æèãã䟡å€ããããŸãã
ãŸãšã
browser-slot.sh ãä»ã®åœ¢ã«ãªããŸã§ã«3åã®èª€ç®ããããŸããã
æåã®èª€ç®ã¯ãChromeãéãããšãã仮説ã§ãããã¹ã¯ãªããã®ã³ã¡ã³ãã«ãã®ãŸãŸæ®ã£ãŠããŸããvm_stat äžçºã§ç¯äººãdasdïŒ47GBïŒãšComfyUIïŒ12GBïŒã ãšããããChrome9ååèšã®0.7GBã¯èª€å·®ã§ãããäžé3ãçã¿åºããŠãã1æ¥92ä»¶ã®ã¹ãããã¯ã宿ž¬5åã§è§£æ±ºã§ããåé¡ã§ããã
2çªç®ã®èª€ç®ã¯ãäžéã6ã«æ»ããåŸã®æçš¿ã¬ãŒã³è©°ãŸãã§ããengageãšpostãååã«æ±ã£ãŠããããã«ãæã®åæã¿ã€ã ã¢ãŠãã§æçš¿ã9åé£ç¶ã¹ããããããŸããããç¿åã§ãªã«ããªã§ãããããããšããã®æéåž¯ãæ¶ãããšåãè¿ããªãæçš¿ãã¯ãåãã¹ãããäžéã§ç«¶ãããŠã¯ãããªãã£ããenv倿°2æ¬ã§æžãäºçŽæ ããã®è§£æ±ºçã§ãã¹ã¯ãªããã®å€æŽé㯠is_reserved_group() ã®è¿œå ãš acquire_slot() ãžã®4è¡å·®ã蟌ã¿ã ãã§ããã
3çªç®ã®èª€ç®ã¯ã¿ã€ã ã¢ãŠã倿°ã®äºé管çã§ããplistã«æžãã AUTOLIKE_TIMEOUT_SEC=3700 ãPerlã¹ãŒããŒãã€ã¶ã® BROWSER_SLOT_TIMEOUT_SEC ã«å±ããŠããªããŸãŸæ°æ¥åããŠããŸãããrun-account.sh ã§ã®1è¡ã®åãæž¡ãã§è§£æ±ºããŸãããããèšå®ããã®ã«åæ ãããŠããªãããšããçç¶ã¯ãã°ãæ£çŽã«åå ãæããŠãããªãã®ã§ç¹ã«çºèŠãé
ããŸãã
3ã€ã«å ±éããã®ã¯ãçŽæã«ããèšå® â 宿ž¬ã®æ¬ åŠ â éããªèª€åäœããšãããã¿ãŒã³ã§ããChromeã®éãããã¹ãããç«¶åããã¿ã€ã ã¢ãŠãã®æ¥ç¶ããã©ãããåããŠããã®ã«å®è³ªæ©èœããŠããªãããšããçç¶ã§ããã°ãéèšãããŸã§çºèŠããŸããã§ããã
èªååã¯ãã³ãŒããåããŠããæ¬çªã§å£ããããã®ã§ããå£ãæ¹ãéãã§ããã»ã©ã宿ž¬ãšãã°éèšãå¯äžã®èšºæææ®µã«ãªããŸããã»ããã©ã®ä»çµã¿èªäœããããã©ãã宿ž¬ãã¹ããããšãäœãéèšãã¹ããããæåã«æ±ºããŠããæ¹ããé·ãå®å®ããŠåãèªååãäœãè¿éã§ãã
ä»çµã¿ã®å šäœåã»æ120äžã®å èš³ã»30æ¥æé ã¯æænoteã«ãŸãšããŠããŸãã ð Claude CodeèªåŸç°å¢ã§ãå®éã©ã皌ãã â ä»çµã¿ã»å®äŸã»å§ãæ¹ã»ãµããŒã
LilyïŒ@bokuwalilyïŒâ å人éçºè ãClaude Code ã§èªåååºç€ãçµã¿ãªãããiOSã¢ããªãWebãµãŒãã¹ãéç£ããŠããŸã
- AIã§ãå¯ãŠãŠãåãä»çµã¿ããäœã£ãŠæ120äžã«ãã話㯠noteã®ææèšäº ã«ð°
- OSS: github.com/bokuwalily ð
- ææ°æ å ±ã»ãåãåãã㯠X @bokuwalily ãžð
- AIå°å ¥ã»èªååã®çžè«ãšå®è£ ãã³ãã¬7æ¬ã®é åžã¯ å ¬åŒLINE ããð¬
çããã® â€ïž ãã·ã§ã¢ãå±ã¿ã«ãªããŸãïŒ