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

Implement pre-compilation of exercises and graders #481

Merged
merged 41 commits into from Nov 3, 2023

Conversation

AltGr
Copy link
Collaborator

@AltGr AltGr commented Apr 1, 2022

Close #478, Close #414, Close #205, Close #312, Close #158

@AltGr AltGr marked this pull request as draft April 1, 2022 12:47
@AltGr
Copy link
Collaborator Author

AltGr commented Apr 1, 2022

This replaces the prepare.ml, solution.ml and test.ml files that were sent scrambled and evaluated textually in the grader's toplevel by compiled files (interfaces in cmi, implementation in cma and js depending on the backend).

The main benefit is two-fold:

  • it's now impossible to extract the solution (or grader) from a running server: only the compiled version — useless for cheating — is available

  • it's much more efficient:

                              MASTER  PRECOMPILE
      build -j1               1005s   33s
      build -j12              (broken)7.6s
      loading exercise        5.8s    5.2s
      grading (100%)          6.4s    4.0s
    

(these have been run on the learn-ocaml-corpus repository and the markov exercise, respectively. Check my (temporary) patches here)

That's a 132x speedup on learn-ocaml build in the best case!

Todo:

  • re-implement depend.txt handling (or replace it with something more powerful, it fits much better in the new backend and will only be needed at build-time); and check that the (temporarily disabled) mutations_test.ml works with it
  • add the ppx to introduce the register_sampler calls that are now required (@hernoufM)
  • samplers are not properly type-checked yet
  • one grader of the corpus segfaults (week5/seq1/ex2) (but see point just above!)
  • asak/solution partitioning is disabled: if someone knowing that part of the code could have a look, @nobrakal ?
  • restore feature to define custom printers
  • check how to handle the emacs-mode with the new server (@erikmd ?)
  • check that the small changes required in exercises are OK with users (in progress on the mailing-list)

@erikmd erikmd added the kind: feature New user-facing feature. label Apr 1, 2022
@erikmd erikmd added this to the learn-ocaml 1.0.0 milestone Apr 1, 2022
@AltGr
Copy link
Collaborator Author

AltGr commented Apr 21, 2022

This should finally be all good feature-wise. Last bits:

  • Some documentation
  • Fix static builds / docker containers ; building an exercise repository now requires ocamlc to be available

@AltGr AltGr marked this pull request as ready for review April 21, 2022 17:35
@AltGr AltGr force-pushed the a7977b52 branch 4 times, most recently from 0699cef to d348acb Compare April 22, 2022 15:41
@AltGr
Copy link
Collaborator Author

AltGr commented Apr 22, 2022

This is finalised and, I think, ready to review and go!
Report on the status of the tests:

  • ✔️ building the static binaries works fine
  • ✔️ building the Docker images and running the dockerised tests work fine
  • 🟠 Build learn-ocaml and run tests uses master of learn-ocaml-corpus. There are some small changes required, detailed in this PR. These should be backwards-compatible¹ and I can confirm running the test locally with that branch of the corpus works.
  • ✔️ Build learn-ocaml-client and run quick tests works on the current version image
  • 🔴 Build learn-ocaml-client and run quick tests (ocamlsf/learn-ocaml:0.12/0.13.0): these tests check for HTTP API compatibility with learn-ocaml 0.12 and 0.13.0, which is a non-goal of this PR (we don't want to provide solution.ml files in any form anymore!). A major version bump is in order, and this will only affect users of the command-line client.

¹ at the loss however of the installed printers, on older versions of learn-ocaml, since they relied on the #install_printer directive which we can't keep, and they don't have the new mechanism. If this is a problem we can have a separate branch in learn-ocaml corpus and point the test to that.

@AltGr
Copy link
Collaborator Author

AltGr commented Apr 22, 2022

Ah, I forgot to add the copyright headers to all the new files. [EDIT: done]

@erikmd erikmd self-assigned this Apr 28, 2022
@AltGr
Copy link
Collaborator Author

AltGr commented Jun 4, 2022

I know some teachers who were expecting this to be at least merged for their classes in June; can we go forward, or should I advise them to use an unofficial branch ?

@erikmd
Copy link
Member

erikmd commented Jun 7, 2022

@AltGr thanks for your ping 👍. Sorry, was swamped with teaching lately, my plan actually is to integrate it as soon as possible once:

  1. asak-partitioning implementation is updated (I will email Alexandre to arrange some meeting slot soonish)
  2. learn-ocaml.el mode is updated (will be easy AFAICT, will let you know ASAP)
  3. and ideally after discussing with you, to figure out some way to keep compatibility with learn-ocaml-editor! 🙏
  4. and finally after a slight-multi-squash to be fully release-please compliant

As a result, I'm afraid the feature won't be released this month, but definitely in July for September.

@nobrakal
Copy link
Contributor

nobrakal commented Jun 7, 2022

Woops, I am really sorry for my lack of reply, I did not see the previous mention.

I wonder if anyone actually uses the partitioning feature, I hope this is not a release-blocker.

Anyway, even if I lack the time to implement any modification by myself, I am available to review or discuss any change if needed.

@erikmd
Copy link
Member

erikmd commented Jun 7, 2022

Hi!

Woops, I am really sorry for my lack of reply, I did not see the previous mention.

No worries, @nobrakal !

I wonder if anyone actually uses the partitioning feature,

I think so (and hope so :)

I hope this is not a release-blocker.

But even if we don't have usage statistics, I think it is a "release-blocker", at least given the asak-partitioning feature was part of the previous stable releases of learn-ocaml!

Anyway, even if I lack the time to implement any modification by myself, I am available to review or discuss any change if needed.

OK, thanks… anyway we'll be able to discuss this with @yurug at the end of this week

@AltGr
Copy link
Collaborator Author

AltGr commented Sep 15, 2022

Having rushed to have this ready back in April, I have to say I am pretty disappointed that this hasn't been merged yet, esp. since I told a few teachers that it would be in a release for the semester start in September.

I understand the issue with Asak getting temporarily disabled, but, like @nobrakal, I don't think that should be a release blocker: this is a massive overall improvement for everyone (the 100x speedup on learn-ocaml build is no joke! And the solution hiding was requested by many for a long time) while Asak remains a niche feature. Don't get me wrong, it's a nice one, but if advertised correctly in the new release people who rely on it will know to stay on the current release until ported, while not holding the others back. The fact that the feature is not yet visible in the interface should help here, too (you have to know to middle-click on a specific item).

@AltGr
Copy link
Collaborator Author

AltGr commented Sep 15, 2022

@yurug I see you made attempt to repair Asak, thanks! did it work ? The patches make prepare.ml visible to learn-ocaml build but not further on a built instance and I was thinking that the partitioning was taking place on a running instance.

I don't remember precisely how Asak works but I think it should in theory be fine with just the cmi for prepare.ml ?

@erikmd
Copy link
Member

erikmd commented Sep 20, 2022

Hi @AltGr, thanks a lot for your messages!, and for this very nice work 🙏

Having rushed to have this ready back in April, I have to say I am pretty disappointed that this hasn't been merged yet, esp. since I told a few teachers that it would be in a release for the semester start in September.

I fully understand—AFAICT, my OCaml lab sessions precisely start this week, and I would have loved to benefit from #481.

No need to tell many details about the "why", but Yann and I got much less time than expected lately.

BTW:

  • If ever #475 had been implemented, PR #481 would immediately be "available" / easy to deploy by relying on static binaries, without any release. So I just labelled #475 as good first issue in passing 🙂

  • Also the CI was broken till a few days ago… (the fix was simple; but before that moment, doing any release was impossible).

  • Finally, you mentioned the asak issue (which is not an undocumented feature BTW 😉) but this is not the very last small point that remains to address.

  • Anyway, @yurug and I restarted last week our recurrent learn-ocaml maintainer telco; so, no ETA; but stay tuned 👍

@gasche
Copy link
Contributor

gasche commented Nov 14, 2022

@erikmd and @yurug : gentle ping, have you been able to make progress on integrating this PR?

@erikmd
Copy link
Member

erikmd commented Dec 29, 2022

gentle ping, have you been able to make progress on integrating this PR?

@gasche sure! as said previously, this PR is a priority! in particular as soon as the bugfix PR #506 is merged (certainly at our next learn-ocaml maintainer telco), we'll make a point release, then work on this PR #481. We'd also like to invite @AltGr at that point so that we can talk together with @yurug for the last steps of the review.


let use_compiled_string code =
(* jsoo supports dynload, but relies on expectations on the parent object that
are no longer valid when running from a web-worker. Thus we compile with
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it no longer valid ? Can anything be done on the jsoo side ? Consider opening a jsoo issue.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha, I am sorry, that was too long ago for me to remember precisely 😬
Indeed this could probably be worked around in jsoo; from what I remember, just trying to dynload from within a webworker is enough to point to the issue, with errors about stuff missing from the parent object.

AltGr and others added 18 commits November 3, 2023 13:55
`learn-ocaml build` now requires write access to the repository since it writes
compilation artefacts in-place.
Signed-off-by: Yann Regis-Gianas <yann@regis-gianas.org>
Signed-off-by: Yann Regis-Gianas <yann@regis-gianas.org>
…haywire

An uncaught exception could get caught upper on the stack, and lead the worker
to start running pending lwt stuff that belong to the master..

Also attempt to fix "too many open files" error with many workers
since the libraries are already available
It's not expected that we remain compatible with versions that required exposing
`solution.ml`.
these are required for compiling certain exercises
@AltGr AltGr self-assigned this Nov 3, 2023
@AltGr AltGr merged commit 6356328 into ocaml-sf:master Nov 3, 2023
12 checks passed
AltGr added a commit to AltGr/learn-ocaml that referenced this pull request Nov 3, 2023
Closes ocaml-sf#529 which seemed to be a common complaint among teachers.

* `learn-ocaml serve --replace` will kill an existing server (running on the
  same port) just before starting

* `learn-ocaml build serve` with an existing server on the same port will fail
  fast (before actually doing the build)

* `learn-ocaml build serve --replace` is more clever:
  - it will do the build *in a temporary directory*
  - then, only if everything is ok, kill the older server
  - swap the files and start the new server

This is all done in order to minimise downtime and be convenient for server
updates.

Note that this PR sits on top of ocaml-sf#481 and should be rebased once it's merged.
@erikmd
Copy link
Member

erikmd commented Nov 3, 2023

Hi @AltGr, thanks for the merge!, but please wait for the learn-ocaml.el and learn-ocaml-client fixes before we can release 1.0.0 🚀

@gasche
Copy link
Contributor

gasche commented Nov 3, 2023

Congratulations for the merge!

@AltGr
Copy link
Collaborator Author

AltGr commented Nov 3, 2023

@erikmd Of course! Porting them should be less tedious now that this is merged

@AltGr
Copy link
Collaborator Author

AltGr commented Nov 3, 2023

It'll probably be worth releasing a 1.0~beta asap, to have a little more testing before the final release

@erikmd
Copy link
Member

erikmd commented Nov 3, 2023

Hi @AltGr,

More testing would be nice indeed!, but I think this does not require doing a beta release at all
(all the more as release-please does not support beta releases AFAIK).

Indeed, end users can already use the ocamlsf/learn-ocaml:master Docker image,
or the static binaries attached to the ✔️ last master commit.

Anyway, maybe you could prepare an announcement text mentioning ocamlsf/learn-ocaml:master and post it on https://discuss.ocaml.org? WDYT?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment