chore: baseline V8.10.0-dev.1 with v8_workflows type-mapping fix and trade-pro spec
- SiteForge Enterprise V8.10.0-dev.1 upstream source (210 tests) - Fix: v8_workflows._mapped_input now reads both 类型/分类 columns so WXR imports keep post/product types instead of collapsing to page - Docs: trade-pro theme port spec (R3) and implementation plan Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
"""Optional Redis wake-up channel; database remains authoritative job queue.
|
||||
|
||||
Redis outages degrade to timed polling and never lose durable jobs. A bounded
|
||||
list prevents idle systems accumulating unbounded notification entries.
|
||||
"""
|
||||
import os,socket,ssl,time
|
||||
from urllib.parse import urlparse,unquote
|
||||
|
||||
URL=os.getenv('SITEFORGE_REDIS_URL','')
|
||||
|
||||
def _command(sock,*args):
|
||||
payload=b'*'+str(len(args)).encode()+b'\r\n'
|
||||
for arg in args:
|
||||
val=str(arg).encode()
|
||||
payload+=b'$'+str(len(val)).encode()+b'\r\n'+val+b'\r\n'
|
||||
sock.sendall(payload)
|
||||
buf=sock.makefile('rb')
|
||||
line=buf.readline()
|
||||
if not line:raise OSError('Redis disconnected')
|
||||
if line[:1]==b'-':raise OSError(line[1:].decode(errors='replace'))
|
||||
if line[:1] in (b':',b'+'):return line[1:].strip()
|
||||
if line[:1]==b'$':
|
||||
size=int(line[1:].strip())
|
||||
return buf.read(size+2) if size>=0 else None
|
||||
if line[:1]==b'*':
|
||||
count=int(line[1:].strip())
|
||||
for _ in range(max(count,0)):
|
||||
n=int(buf.readline()[1:].strip());buf.read(n+2)
|
||||
return count
|
||||
raise OSError('Unexpected Redis response')
|
||||
|
||||
def _socket():
|
||||
u=urlparse(URL)
|
||||
if u.scheme not in ('redis','rediss'):raise ValueError('Redis URL requires redis/rediss')
|
||||
s=socket.create_connection((u.hostname,u.port or 6379),timeout=3)
|
||||
s.settimeout(4)
|
||||
if u.scheme=='rediss':s=ssl.create_default_context().wrap_socket(s,server_hostname=u.hostname)
|
||||
if u.password:_command(s,'AUTH',unquote(u.password))
|
||||
if u.path and u.path not in ('','/','/0'):_command(s,'SELECT',int(u.path.strip('/')))
|
||||
return s
|
||||
|
||||
def notify():
|
||||
if not URL:return False
|
||||
try:
|
||||
with _socket() as s:
|
||||
_command(s,'LPUSH','siteforge:build:wakeup',1)
|
||||
_command(s,'LTRIM','siteforge:build:wakeup',0,1023)
|
||||
return True
|
||||
except (OSError,ValueError,TypeError):return False
|
||||
|
||||
def wait(fallback=1.5):
|
||||
if not URL:
|
||||
time.sleep(fallback);return
|
||||
try:
|
||||
with _socket() as s:_command(s,'BRPOP','siteforge:build:wakeup',1)
|
||||
except (OSError,ValueError,TypeError):time.sleep(fallback)
|
||||
Reference in New Issue
Block a user