Conversation
|
I guess you had to go this way to avoid the overhead of asking and waiting for the editor for every lookup tentative? |
|
Most likely. I think this approach should reduce work for editors in general, as now engine will directly request the files it needs and no guessing logic needed. If editors can implement batch mode for these requests then the performance difference should be negligible. I plan to test it out with texpresso.vim as soon as we merge all 3 phases. For now restart cost was estimated very roughly, but I feel this won't be critical. |
|
Ok, I think we can proceed with this approach. Let me review a bit more thoroughly. Independent but related idea: what about allowing the editor to push just the filenames, and have the engine pull a file when a lookup happens on a known but unpushed file? |
Oh, that's could be interesting. I am thinking of
This eliminates the restart cycle entirely for known files. The engine just pauses, gets the content, and moves on. This is safe to block because the editor made an explicit promise (unlike You think it can be added as phase 4? :) |
I was just sharing my thoughts, feel free to add it if it matches the workflow you have in mind. Thinking more about the problem, I am not super satisfied by Let me suggest another strategy (you tell me if it is inappropriate) which requires no change to the engine. Everytime the driver is not able to satisfy a lookup, it also writes a message to the editor about the filename that failed to be satisfied (e.g. adding a function The editor can then decide to push (or not) based on the filename. This way, the editor will also see the different attempts (e.g. when using |
|
Well, the issue with this approach is engine will emit But you're right having duplicated logic is messy, I'll simplify it to return |
a7098aa to
fbf4018
Compare
|
Apologies, but I will be a bit annoying on this one, since the other solution is so simple and seems to be able to cover your use-case. I made a proof-of-concept implementation, here is the lookup output for compiling test/simple.tex: Wouldn't that be sufficient for what you have in mind? |
|
I agree it will be much simpler, but the thing is I don't like that 1) it clutters the traffic and make editor respond to every I have tried this solution before, but it just generated to much noise. I would vote on clean, but more complex solution then simple, but noisy. |
These messages will be buffered and asynchronous (the driver is not waiting for an answer), this is essentially free.
The driver could skip the lookup-file messages for the ones that could be answered by kpathsea. However that breaks the case where someone overrides a kpathsea provided file with their own version (which is also not supported by OPLR). Alternatively, the lookup-file message could also contain this information, and let the editor decide what to do (as I said, lookup-file messages are essentially free, they might clutter the log, but one can just grep them away if they need to read the log). |
As I understand in both solutions this still be an issue, but for now I don't think we need to care. Okay, I have looked through my further implementation, and I think you're right on However, I would highly suggest adding Should I close this PR or I can push the lookup-file changes instead? |
At least when it sees a lookup-file message, the editor knows that it should push the file if it is in its workspace.
Yes, I think #126 will be good. Another issue is that on startup, TeXpresso immediately starts processing the document, which do not give the editor the opportunity to populate the initial file system.
You can if you are in hurry. Since we are still working out the design, I don't mind waiting a few more days to iron out other possible issues (and maybe go back to OPLR). |
Yes, now is up to editor to decide.
Hmm, I think editor can do preparation to pre-fetch all the paths it needs, but it (maybe?) can cause a race conditions issue with TeXpresso immediate response.
Not at all. I will be glad to find the approach we will be comfortable with. The other project I am developing separately, and stream mode will be needed to properly link texpresso with it, but the linker it can wait. |
Yes, that's what I was thinking about. Maybe it does not matter (it will cause one initial backtrack once receiving the FS information from the editor). If it does, texpresso we could add an option to start in a "pause" mode, waiting for start/resume command from the editor. |
|
I think having Preserving its state is nice, and it seems very easy to implement. |
|
Hey @let-def! Have you got a chance to look at the stream mode? |
|
@merv1n34k I opened #127 which just adds the lookup-file message. |
Hey!
Closes #120 phase 3. The implementation I come up with is quite interesting, although I am not sure if is does not bear any noticeable performance issues.
Report
feat: add non-blocking request-file via Q_OPRL last-resort query
Idea: Phases 1 and 2 let the editor push files, but there's no way for the engine to pull -- if it needs a file that kpathsea can't resolve and the editor hasn't pushed yet, it just fails. New protocol query
Q_OPRL("Open Read Last-resort") is sent by the engine only after all local fallbacks have failed:Q_OPRD-> driver VFS/disk ->A_OPENorA_PASSfopen()-> local diskQ_OPRL->A_PASSimmediately +request-filenotification <- newNULLif still unresolvedDetails
texpresso_protocol.c/h: NewT_OPRLtag andtxp_open_last_resort()function (identical totxp_openbut sendsT_OPRL, always READ mode).main.c(engine): Callstxp_open_last_resort()at the end ofttstub_input_openafter all fallbacks fail.sprotocol.h/c: NewQ_OPRLquery enum value, parsing and logging.engine_tex.c:Q_OPRLhandler with two branches -- if file is already in VFS (edit_data), respondA_OPEN; otherwise respondA_PASSand emitrequest-filevia stdout.editor.c/h:editor_request_file()outputsrequest-file "path"message.EDITOR-PROTOCOL.md: Documents the new message.Design decisions:
Q_OPRL always returns A_PASS immediately and Restart via existing rollback
Q_OPRLalways returnsA_PASSimmediately. Why not block?Q_OPRLfires for all unresolved files, including.auxon first run. TeX handles missing.auxgracefully (writes a fresh one), but a blocking query would hang forever for files the editor can't provide. Research into XeTeX source confirmed only\inputand format loading are fatal onNULL-- everything else (.aux,\openin, fonts, pictures) handles it fine, and there's no engine-side flag to distinguish them.open,interpret_openstores it inedit_data->notify_file_changes->rollback_processeskills the dead engine ->prepare_processforks from snapshot -> new engine sendsQ_OPRD-> driver finds file in VFS ->A_OPEN-> compilation succeeds. Multiplerequest-filemessages can fire in one run; the editor batches allopenresponses and a single restart resolves all of them.Q_OPRL.fix: interpret_open relative path handling
Issue:
relative_path()was called unconditionally on paths fromopencommands. Files provided viarequest-fileresponses use relative paths, which got rejected as "different root."Fix: Guard
relative_path()behindpath[0] == '/'so relative paths pass through directly.fix: -test-initialize exit condition
Issue: With non-blocking
Q_OPRL, the engine can die before producing pages (e.g.\inputof a missing file). The oldinitialize_onlycheck exited immediately without giving the editor a chance to provide files.Fix: Exit on
page_count > 0(success) orDOC_TERMINATED && stdin_eof(engine died and no editor is connected -- no recovery possible).chore: add CI
test/request-file.tex: Document that\inputs a non-existent file.test/test-request-file.sh: Integration test using FIFO -- waits forrequest-fileon stdout, provides the file via stdinopencommand, verifies engine exits successfully.Makefile:make test-request-filetarget.New capabilities
I had more use cases, but I think these are the most powerful, correct me if I'm wrong on something. We can also add a note to README if you want. With phases 1 (
-stream), 2 (open-base64), and now 3 (request-file):root.texfilerequest-filekpathseawithout editor involvementopen, TeXpresso pulls viarequest-file