Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for a PostModifier start/end of life-cycle method #213

Open
hmf opened this issue Dec 8, 2019 · 6 comments
Open

Request for a PostModifier start/end of life-cycle method #213

hmf opened this issue Dec 8, 2019 · 6 comments

Comments

@hmf
Copy link

hmf commented Dec 8, 2019

Hope I am not overstepping my bounds here but I have a use-case that I cannot get around and this request seems to be a good way to solve it. Any suggestion for an alternative workaround is welcome. Some background and context. I am using a PostModifier to process code fences that generate plots via a JavaScript library (in this case PlotlyJS). In order to generate static documents (PDF) via Laika I need to render and convert those plots into raster images (png, tiff, etc). To do this I need to instantiate a JavaFX application (with a WebKit component) that will execute the JS script and render the plots headless to files.

So what is the problem? This process is executed as a Miil module (akin to an SBT plug-in) in a forked JVM. Because of the JavaFX application daemon thread, the spawned job will not terminate. In order to termnate this task I need to explicitly stop the headless javaFX application. However I can only do this when I know that MDoc has finished all processing. Hence the request to add such a method. Here I can place a call that stops the javaFX thread. Once no more files need processing, MDoc closes the PostModifier.

So my question are: is this viable and acceptable? Are their mechanisms for me to do this shutdown without the need for such changes?

TIA

@hmf hmf changed the title Request for a PostModifier start/end of life-cycle callback method Request for a PostModifier start/end of life-cycle method Dec 8, 2019
@olafurpg
Copy link
Member

olafurpg commented Dec 8, 2019

Thank you for reporting! Big 👍 from me. Would you be interested in contributing this feature?

One question: how should the start/end methods work under --watch mode?

You might be able to get some inspiration for how to implement this by looking at postProcess on PreModifier

def postProcess(ctx: PostProcessContext): String = ""

@olafurpg
Copy link
Member

olafurpg commented Dec 8, 2019

Example: the mdoc:js modifier is a PreModifier that collects all mdoc:js code fences during process

During postProcess, we use the Scala.js compiler to link a JavaScript file and add links to the generated JS

def postProcess(ctx: PostProcessContext, compiler: MarkdownCompiler): String = {

@hmf
Copy link
Author

hmf commented Dec 9, 2019

@olafurpg Ok, I will take a look at the links you show and see what I can come up with.

In regards to the --watch flag I confess I did not think about this. I will have to give it some more though. But right now I think that the strategy I outlined above will won't work. The JavaFX platform cannot be started more than once per JVM.

Will come back to you on this.

@olafurpg
Copy link
Member

olafurpg commented Dec 9, 2019

One thing we can do it several callbacks for different events 🤔

  • add onExit: before mdoc is shutting down
  • add onWatchIterationEnd: after completing compilation after a single --watch iteration

@hmf
Copy link
Author

hmf commented Dec 10, 2019

I had to revisit the stuff I made in order to determine how to stop/start the JavaFX application and this can be used within MDoc. I have two sets of operations:

  1. One that starts and stops the JFX platform and application
  2. One that starts the JFX platform once and keeps it alive but restarts the application

Seem to be working correctly.

We have 2 different cases:

  1. Lunching MDoc and executing the PostModifier in a forked JVM once
  2. Lunching MDoc and executing the PostModifier in the build tool JVM repeatedly

The problem here is how to support both scenarios at the same time. In case 1 I can start and stop both platform and application with a postProcess method (the constructor will be used for the start). That solves the issue.

In case 2 I would have to :

  1. Initialize the Platform when MDoc starts up
  2. Start the application when the PostModifier starts (use the constructor?)
  3. Stop the application when the PostModifier stops
  4. Stop the Platform when MDoc stops

The above steps lets us use MDoc with --watch (no need to restart between watches). It also subsumes case 1. So I would need 4 methods:

  1. MDoc onStart
  2. PostModifier preProcess
  3. PostModifier postProcess
  4. MDoc onExit

Don't know if a onWatchIterationEndmay be useful for someone else.

Is this ok? Can it be done with minor changes to the current code base ?

TIA

Side note:

I am using MDoc as a Mill task. Mill has the -w/--watch and .runBackground modes. This means that I will use Mill to scan and check for any changes in the MDoc sources. Not as efficient as MDoc's watch but it allows me to play nicely with the build tool's interactive mode. I can try using MDoc directly but will experiment with this later.

@olafurpg
Copy link
Member

@hmf thanks for the update. Feel free to add only the hooks that you need. We can add onWatchIterationEnd separately.

I am using MDoc as a Mill task. Mill has the -w/--watch and .runBackground modes.

The reason mdoc has its own --watch is to be able to reuse the compiler instance between compilations. The 2nd/3rd/... compilations are usually 10x faster than the 1st compilation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants