2026/03/25
|
Wednesday, March 25, 2026 (#84)
|
|
References |
Manual Coarse-Grained Step-Through Debugging
- [Schema]
::EnsureSchema():$oEngine = $this->OEngine();$oClient = $oEngine->OClient();- (in "if" clause)
$oClient->SchemaExists($sSchema)-- this is why we need the schema-list - [Client]
::SchemaExists()eventually ends up at [Client]::NewSchemaList()(first time through, anyway):$oCmd = CmdLineClass::FromString($oSyntax->ListSchemas());$oCmd->QORunner()->CopyIt($qoRun);$oCSListen = new BufferClass;$oCmd->QOListener()->SetIt($oCSListen);$oCSErrors = new ScrnErrsClass;$oCmd->QOErrorBin()->SetIt($oCSErrors);if ($qoRun->HasIt()) { $oRSLecture = $qoRun->GetIt()->OLecture(); UpdateClass::FromEngine($this->OEngine(),$oRSLecture); #$this->AmHere('SET UPDATER '.UpdateClass::class.' on '.get_class($oRSLecture)); $oRSLecture->AmHere('<- LECTURE OBJECT'); $qoRun->GetIt()->OListen()->AmHere('<- LISTEN OBJECT'); } if ($inSeq) { // keeping process open -- just send commands directly $oRun = $this->QORunner()->GetIt(); } else { // this is a one-shot -- send commands through the filter-chain $oRun = $oServer; } $oActCmd = $oRun->DoCommand($oCmd); $oRun = $oCmd->QORunner()->GetIt(); $oRun->DoInOutLoop();
- [Runner]
::DoInOutLoop():while ($doLoop) {$oOpNew = $oCanals->ConveyCheck();- [Canals]
::ConveyCheck():- Currently has 2 Canals to iterate through (what happened to #3, Errors?):
- 1: id=5374 (proc stdout) process stream ⇒ id=5388 buffer stream
- 2: (we don't get to this one)
- Currently has 2 Canals to iterate through (what happened to #3, Errors?):
Diving into that next-to-last item:
- [Canal #1, $oSrce is 5374 ⇒ $oDest is 5388]
->ConveyCheck()⇒->ConveyNow():$qoUpd = $oSrce->QOUpdater();$doILoop = $ok = $oSrce->HasMore();while ($doILoop) {// while there's input to process --if (empty($sGot)) {// if buffer is empty --$oGot = $oSrce->PullBytes(self::IBUFF_SIZE);$qoUpd->OnIterate();
The problem here is that the Updater object ($qoUpdate->GetIt()) is not set, so $qoUpd->OnIterate() doesn't do anything.
Look back through the trace to find where it was supposed to be set, what I find instead is a tangle of different Stream-objects. I think I need a dramatis personae. Looking at the various items that show up in the debugging output:
- 5374 (proc stdout) process stream ( ⇒ id=5388 buffer stream )
- 5388 buffer stream (receives from 5374 proc stdout); set up as LISTEN in the Client, does have an Updater
- 5389 a SRCE Exec Stream in a Conveyer, apparently sending to 5388, does not have an Updater
What I'm seeing here is that at one point it was 5374⇒5388, but then later it seems to be 5389⇒5388. Wot do be hopnin heer.
- Even if it's somehow ok for 5374 to be replaced by 5389, we need an Updater on whichever one of those is being used.
10:17
I added caching of the Stream objects in [WFe]IO\Aspect\Connx\aux\A\caPool because it seemed possible that the overwriting was happening there (creating a new Stream instead of retrieving an existing one), and now all the object IDs are renumbered. ...but! The end result is that a Stream that did not have an Updater now has one. Check and see if anything is working better? (i.e. remove die())
10:55
Although it still gets stuck, we do at least have on-screen updates now -- so I can use that as my debug viewer instead.
12:12
More to the point, the Updater is supposed to invoke the code which contextually determines if we've received what we need, and then sets the flags for EoF -- which I haven't written yet because I need to try some things and see what works.
12:52
The problem now is retrieving the correct Stream for the Engine to look at when CheckStream() is called. I keep thinking I'm passing it the Listener buffer (which accumulates all data received -- I'm hoping there will be something obvious like a pair of CRLFs or newlines at the end), but what I get is an Exec stream...
The current dramatis personae, in ID order:
- 5358
[WFe]\IO\Aspect\Connx\Stream\Native\cExec(LISTEN in Proc i.e. $oRun) - 5361 - process stream: stdout -
[WFe]\IO\Aspect\Connx\Stream\Native\cExec(SRCE in Conveyer)- ⇒ id5391 buffer stream
- 5365 - process stream: stderr
- ⇒ id5374 screen
- 5374 - screen
- ⇐ id5365 process stream: stderr
- 5391
[WFe]\IO\Aspect\Connx\Stream\Finite\cBuffer(LISTEN in Client i.e. $this, DEST in Conveyer)- ⇐ id5361 process stream: stdout
...so, yeah, what's happening to id5358? What is it supposed to be listening to?
13:18
id5358 is $oCSListen:
$oCSListen = new BufferClass;$oCmd->QOListener()->SetIt($oCSListen);
...argh, the numbers keep changing...
(I'd be tempted to try to add some kind of enumeration-feature to Ferreteria classes (call it FOID, for Ferreteria Object ID), but I don't think there's any quick way to be sure that the counter-code will be executed. I'd have to start throwing errors whenever an FOID was requested but hasn't been set... oh but wait, here's a thought: assign the numbers at request time, if not already set...)
20:05
That turned out to be easy, actually -- I replaced this code in [WFe]Sys\Diag\Util\tHelper:
public function ObjectID() : int { return spl_object_id($this); }
...with this:
private static $idFO_Next = 0;
private $idFO = NULL;
public function ObjectID() : int { return is_int($this->idFO) ? $this->idFO : ($this->idFO = self::$idFO_Next++) ; }
20:34
So, once again, the dramatis personae but with IDs that will hopefully be a little less mutable (as long as I don't change the order in which I first access the IDs, anyway):
- 1
[WFe]\IO\Aspect\Connx\Stream\Finite\cBuffer->NewSchemaList(): <= LISTEN (in Client); Cmd Listener; ConveyNow() DEST - 2
[WFe]\IO\Aspect\Connx\Stream\Native\cExec->NewSchemaList(): <- LISTEN OBJECT (in Conveyer) - 3 process stream: stdout; ConveyNow() SRCE
- ⇒ 1 buffer stream
- 5 process stream: stderr
- ⇒ 6 screen
- 6 screen
- ⇐ 5 process stream: stderr
Non-streams:
- 4
[WFe]\IO\Aspect\Connx\cConveyerconnecting id3 => id1 - 7
[WFe]\IO\Aspect\Connx\cConveyerconnecting id5 => id6 - 8
[WFe]\IO\Aspect\Connx\aux\A\cCanalschecking canal connecting id3 => id1
...now, what was I trying to figure out again? 🤔
22:27
The stream the Updater has ended up with is id3 -- but I think what we want is id1, the Listener memory-buffer.