feat(mcp): расширить управление маршрутизацией, доступом и обслуживанием базы
This commit is contained in:
1 parent
9240e8be11
commit
cffcfada88
125 files changed
+6021
-602
No files matched your search
@@ -19,6 +19,11 @@ const {createStorageDurableServerPollSession:createDurableServerPollSession}=awa
|
||||
const {SERVER_PARTITION_WRITER_LOCK}=await import("./server-partition-maintenance-lease.js")
|
||||
const {withPartitionWrite,PartitionWriteError}=await import("./partition-write-transaction.js")
|
||||
const {ensurePartitionFor,PARTITION_SPECS}=await import("../db/partitions.js")
|
||||
const {compactCompletedServerPollStorage}=await import("./server-poll-terminal-compaction.js")
|
||||
const {collectExpiredServerPollStorage}=await import("./server-poll-storage-retention.js")
|
||||
const {tickMcpWorkers}=await import("../modules/mcp/workers.js")
|
||||
const {ServerPollJournalOutcomeUnknown}=await import("./server-poll-journal.js")
|
||||
const {Client}=await import("pg")
|
||||
const security=await import("../modules/mcp/security.js")
|
||||
let serverId:number|undefined,requests=0,releasedNative=false,writerPid=0
|
||||
let releaseNative!:()=>void,firstNative!:()=>void
|
||||
@@ -40,6 +45,20 @@ try{
|
||||
assert.equal((await pool.query("SELECT count(*)::int AS n FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace WHERE n.nspname='public' AND c.relname=ANY($1) AND c.relkind='r'",[["server_poll_executions","server_poll_intents","server_poll_acks","server_poll_receipts","server_poll_quarantines"]])).rows[0].n,5)
|
||||
assert.equal((await pool.query("SELECT count(*)::int AS n FROM pg_trigger t JOIN pg_class c ON c.oid=t.tgrelid WHERE t.tgname='server_partition_writer_guard' AND t.tgenabled='A' AND c.relkind='p'")).rows[0].n,PARTITION_SPECS.length)
|
||||
assert.equal((await pool.query("SELECT count(*)::int AS n FROM servers")).rows[0].n,0,"Fresh isolated database required; never remove foreign fixtures")
|
||||
await pool.query(`CREATE TABLE owned_poll_journal_pid(relation text,pid int,xid text,exclusive_writer boolean);
|
||||
CREATE FUNCTION owned_poll_journal_observe() RETURNS trigger LANGUAGE plpgsql AS $$BEGIN
|
||||
INSERT INTO public.owned_poll_journal_pid SELECT TG_TABLE_NAME,pg_backend_pid(),pg_current_xact_id()::text,
|
||||
EXISTS(SELECT 1 FROM pg_catalog.pg_locks WHERE pid=pg_backend_pid() AND locktype='advisory' AND classid=0
|
||||
AND objid=8723110 AND objsubid=1 AND mode='ExclusiveLock' AND granted);
|
||||
RETURN NULL;
|
||||
END$$;`)
|
||||
for(const name of ["server_poll_storage_admissions","server_poll_storage_usage","server_poll_executions","server_poll_intents","server_poll_acks","server_poll_receipts","server_poll_quarantines"]){
|
||||
await pool.query(`CREATE TRIGGER candidate_application_statement_guard BEFORE INSERT OR UPDATE OR DELETE ON public.${name}
|
||||
FOR EACH STATEMENT EXECUTE FUNCTION public.server_partition_writer_guard();
|
||||
ALTER TABLE public.${name} ENABLE ALWAYS TRIGGER candidate_application_statement_guard;
|
||||
CREATE TRIGGER owned_poll_journal_observe AFTER INSERT OR UPDATE OR DELETE ON public.${name}
|
||||
FOR EACH STATEMENT EXECUTE FUNCTION public.owned_poll_journal_observe();`)
|
||||
}
|
||||
await new Promise<void>((resolve,reject)=>{listener.once("error",reject);listener.listen(0,"127.0.0.1",()=>{listener.off("error",reject);resolve()})})
|
||||
const port=(listener.address()as{port:number}).port
|
||||
serverId=Number((await pool.query("INSERT INTO servers(name,host,port,enabled,username,password,use_ssl,verify_ssl) VALUES('poll-owned-before','127.0.0.1',$1,true,'SYNTHETIC','SYNTHETIC',false,true) RETURNING id",[port])).rows[0].id)
|
||||
@@ -78,6 +97,22 @@ try{
|
||||
assert(plan.maintenance.some(effect=>effect.kind==="partition.drop"&&effect.name===expired))
|
||||
const pending=session.execute(plan);void pending.catch(()=>{})
|
||||
await Promise.race([started,pending.then(()=>assert.fail("Native request must occur before completion"))])
|
||||
const {rows:[holder]}=await pool.query(`SELECT pid FROM pg_catalog.pg_locks WHERE locktype='advisory' AND classid=0
|
||||
AND objid=$1::oid AND objsubid=1 AND mode='ExclusiveLock' AND granted`,[SERVER_PARTITION_WRITER_LOCK])
|
||||
assert(Number.isInteger(holder?.pid))
|
||||
const prefix=(await pool.query("SELECT relation,pid,xid,exclusive_writer FROM owned_poll_journal_pid")).rows
|
||||
assert(prefix.some(row=>row.relation==="server_poll_executions"));assert(prefix.some(row=>row.relation==="server_poll_intents"))
|
||||
assert(prefix.every(row=>row.pid===holder.pid&&row.exclusive_writer===true))
|
||||
const anchor=prefix.find(row=>row.relation==="server_poll_executions")!
|
||||
assert(prefix.some(row=>row.relation==="server_poll_storage_admissions"&&row.xid!==anchor.xid),"Reservation and consume/anchor are independently committed")
|
||||
assert(prefix.some(row=>row.relation==="server_poll_storage_admissions"&&row.xid===anchor.xid),"Consume and anchor share one transaction")
|
||||
const workerErrors:unknown[]=[]
|
||||
await tickMcpWorkers().catch(error=>workerErrors.push(error))
|
||||
assert.deepEqual(workerErrors,[],"An actual worker tick must defer maintenance without an error while native POLL owns the exclusive lock")
|
||||
assert.equal((await compactCompletedServerPollStorage()).compacted,0)
|
||||
assert.equal((await collectExpiredServerPollStorage()).collected,0)
|
||||
assert.equal((await pool.query("SELECT count(*)::int AS n FROM pg_locks WHERE locktype='advisory' AND pid=$1 AND objid=$2::oid AND mode='ExclusiveLock' AND granted",[holder.pid,SERVER_PARTITION_WRITER_LOCK])).rows[0].n,1)
|
||||
assert.equal((await pool.query("SELECT pg_try_advisory_xact_lock(hashtextextended('server-poll-storage-v1',0)) AS free")).rows[0].free,true)
|
||||
// Actual ordinary writer arrives while FULL poll holds the exclusive lease.
|
||||
// Inspect lock evidence before releasing HTTP; no target relation is touched.
|
||||
const controller=new AbortController()
|
||||
@@ -88,6 +123,8 @@ try{
|
||||
assert.equal((await pool.query("SELECT count(*)::int AS n FROM pg_locks l JOIN pg_class c ON c.oid=l.relation WHERE l.pid=$1 AND l.locktype='relation' AND (c.relname='traffic_samples' OR c.relname LIKE 'traffic_samples_w_%')",[writerPid])).rows[0].n,0)
|
||||
}finally{controller.abort();await assert.rejects(blocked,(error:unknown)=>error instanceof PartitionWriteError&&!error.outcomeUnknown);releaseNative()}
|
||||
const receipt=await pending
|
||||
assert.equal((await compactCompletedServerPollStorage()).compacted,0)
|
||||
assert.equal((await collectExpiredServerPollStorage()).collected,0)
|
||||
assert.equal(receipt.complete,true);assert.equal(receipt.maintenanceComplete,true);assert.equal(receipt.nativeReads,4)
|
||||
assert.equal(receipt.completedPublications,plan.maintenance.length+4)
|
||||
assert.deepEqual([...paths].sort(),["/rest/interface","/rest/ip/address","/rest/system/identity","/rest/system/resource"].sort())
|
||||
@@ -98,6 +135,11 @@ try{
|
||||
assert.equal((await pool.query("SELECT count(*)::int AS n FROM server_poll_intents WHERE receipt_id=$1",[receiptId])).rows[0].n,receipt.completedPublications+4)
|
||||
assert.equal((await pool.query("SELECT count(*)::int AS n FROM server_poll_acks WHERE receipt_id=$1",[receiptId])).rows[0].n,receipt.completedPublications+4)
|
||||
assert.equal((await pool.query("SELECT count(*)::int AS n FROM server_poll_receipts WHERE receipt_id=$1",[receiptId])).rows[0].n,1)
|
||||
const fullJournal=(await pool.query("SELECT relation,pid,xid,exclusive_writer FROM owned_poll_journal_pid")).rows
|
||||
assert(fullJournal.every(row=>row.pid===holder.pid&&row.exclusive_writer===true))
|
||||
assert(fullJournal.some(row=>row.relation==="server_poll_acks")&&fullJournal.some(row=>row.relation==="server_poll_receipts"))
|
||||
assert(new Set(fullJournal.filter(row=>row.relation==="server_poll_intents").map(row=>row.xid)).size===receipt.completedPublications+4)
|
||||
assert.deepEqual(await session.readExisting(plan),receipt)
|
||||
// Measure a COMPLETE real journal, including ciphertext, proofs, timestamps,
|
||||
// admission and every stage. This is sizing evidence, not an archive format
|
||||
// or permission to delete/compact rows. Never print the captured payload.
|
||||
@@ -118,6 +160,39 @@ try{
|
||||
chargedBytes:Number(stored.admission.used_bytes),fullJsonBytes:fullBytes.length,gzipBytes:compressed.length,gzipRoundTripExact:true,
|
||||
sampleFits128KiB:compressed.length<=131072,identityKind:stored.admission.identity_kind,compactionPerformed:false,
|
||||
archiveAuthenticationAccepted:false,historicalVerifierAccepted:false,productionCapacityAccepted:false}))
|
||||
const lostRequest={serverId,receiptId:randomUUID()},lostIdentity={...identity,executionId:randomUUID(),requestId:randomUUID()}
|
||||
const originalAuthority=sessionInput.authorize
|
||||
const lostSession=createDurableServerPollSession({request:lostRequest,identity:lostIdentity,authorize:async(request,ids,signal)=>{
|
||||
assert.deepEqual(request,lostRequest)
|
||||
return originalAuthority(sessionRequest,ids,signal)
|
||||
}})
|
||||
const lostPlan=await lostSession.prepare(),originalQuery=Client.prototype.query
|
||||
type IdentifiedClient=InstanceType<typeof Client>&{processID?:number}
|
||||
let reservedBackend:IdentifiedClient|undefined,acksLost=0
|
||||
try{
|
||||
Client.prototype.query=function(this:InstanceType<typeof Client>,...args:unknown[]){
|
||||
const request=args[0] as {text?:string;values?:unknown[]}
|
||||
if(request?.text?.startsWith("INSERT INTO server_poll_storage_admissions")&&request.values?.[0]===lostRequest.receiptId)reservedBackend=this
|
||||
if(this===reservedBackend&&request?.text==="COMMIT"&&acksLost===0){
|
||||
return Promise.resolve(Reflect.apply(originalQuery,this,args)).then((result:{command:string})=>{
|
||||
assert.equal(result.command,"COMMIT");acksLost++;throw Error("owned real reservation COMMIT ACK lost")
|
||||
})
|
||||
}
|
||||
return Reflect.apply(originalQuery,this,args)
|
||||
} as typeof Client.prototype.query
|
||||
await assert.rejects(lostSession.execute(lostPlan),error=>error instanceof ServerPollJournalOutcomeUnknown&&error.automaticReplay===false&&!error.requiresDurableQuarantine)
|
||||
}finally{Client.prototype.query=originalQuery}
|
||||
assert.equal(acksLost,1);assert.equal(requests,4)
|
||||
const {rows:[lostState]}=await pool.query(`SELECT
|
||||
(SELECT count(*)::int FROM server_poll_storage_admissions WHERE receipt_id=$1) AS charged,
|
||||
(SELECT count(*)::int FROM server_poll_executions WHERE receipt_id=$1) AS anchored,
|
||||
(SELECT count(*)::int FROM server_poll_quarantines WHERE receipt_id=$1) AS quarantined`,[lostRequest.receiptId])
|
||||
assert.deepEqual(lostState,{charged:1,anchored:0,quarantined:1})
|
||||
const {rows:[quarantine]}=await pool.query("SELECT pid,exclusive_writer FROM owned_poll_journal_pid WHERE relation='server_poll_quarantines'")
|
||||
assert(Number.isInteger(reservedBackend?.processID))
|
||||
assert.notEqual(quarantine.pid,reservedBackend?.processID);assert.equal(quarantine.exclusive_writer,false)
|
||||
assert.equal(await lostSession.readExisting(lostPlan),undefined)
|
||||
console.log("Guarded durable POLL journal acceptance:",JSON.stringify({sameHolder:true,independentCommits:true,concurrentMaintenanceNoEarlyChanges:true,workerErrors:workerErrors.length,readExisting:true,realLostCommitAckNoReplay:true,independentQuarantine:true}))
|
||||
sessionRequest.serverId++
|
||||
identity.ownerId="mutated-outer-input";identity.expiresAt=0
|
||||
sessionInput.authorize=async()=>{throw Error("Outer caller replaced authority provider")}
|
||||
@@ -125,7 +200,7 @@ try{
|
||||
await assert.rejects(session.execute({...plan,bindingProof:"0".repeat(64)}));assert.equal(requests,4)
|
||||
await withPartitionWrite(async owner=>{await owner.client.query("INSERT INTO traffic_samples(server_id,interface_name,sampled_at,rx_bytes) VALUES($1,'after-full-poll',now(),1)",[serverId])})
|
||||
revoked=true;await assert.rejects(session.execute(plan));assert.equal(requests,4)
|
||||
console.log("Full durable poll actual SQL/HTTP acceptance:",JSON.stringify({fourNativeGets:requests,maintenanceEffects:plan.maintenance.length,parents:PARTITION_SPECS.length,completedPublications:receipt.completedPublications,sameBackendLeaseAndTransactions:true,ordinaryWriterBlockedBeforeRelationSql:true,realJournal:true,repeatedApplyNoNewNative:true,outerInputMutationCannotReplaceCapturedIdentityOrAuthority:true,changedPlanBindingRefused:true,lateRevocationRefused:true,actualHttpAuthenticationMiddleware:false,productionRegistration:false,externalNetwork:false,authorityReads}))
|
||||
console.log("Full durable poll actual SQL/HTTP acceptance:",JSON.stringify({fourNativeGets:requests,maintenanceEffects:plan.maintenance.length,parents:PARTITION_SPECS.length,completedPublications:receipt.completedPublications,sameBackendLeaseAndTransactions:true,guardedSameHolderJournal:true,separateDurableJournalCommits:true,independentQuarantineAfterRealLostCommitAck:true,ordinaryWriterBlockedBeforeRelationSql:true,realJournal:true,repeatedApplyNoNewNative:true,outerInputMutationCannotReplaceCapturedIdentityOrAuthority:true,changedPlanBindingRefused:true,lateRevocationRefused:true,actualHttpAuthenticationMiddleware:false,productionRegistration:false,externalNetwork:false,authorityReads}))
|
||||
}finally{
|
||||
if(!releasedNative)releaseNative()
|
||||
listener.closeAllConnections();if(listener.listening)await new Promise<void>(resolve=>listener.close(()=>resolve()))
|
||||
|
||||
Reference in new issue
Block a user