Zeitwerk es un cargador de código eficiente y seguro para hilos para Ruby. Mientras el proyecto siga las convenciones de nomenclatura, Zeitwerk puede encontrar los archivos correctos y cargarlos bajo demanda o de antemano, sin necesidad de usar require o require_dependency. Además, según ese artículo https://weblog.rubyonrails.org/2019/2/22/zeitwerk-integration-in-rails-6-beta-2/, podría proporcionar un pequeño aumento de rendimiento a la aplicación.
Hay algunos pasos que debo realizar para que funcione:
Cambiar el nombre de algunas clases para seguir la convención de nomenclatura de Rails. Por ejemplo, el archivo canonical_url.rb debería definir la clase CanonicalUrl en lugar de CanonicalURL. De manera similar, el archivo ondiff.rb debería definir la clase Onpdiff en lugar de ONPDiff. Una alternativa sería conectar un inflector personalizado al proyecto; sin embargo, creo que seguir la convención podría ser una mejor opción: GitHub - fxn/zeitwerk: Efficient and thread-safe code loader for Ruby · GitHub
Al igual que en el punto anterior, por convención, las validaciones personalizadas que residen en el directorio validations deben estar envueltas en el módulo Validations. Además, algunas validaciones heredan de EachValidator y deben ser accesibles sin espacio de nombres. Planeo moverlas a un directorio separado y agregarlas a las rutas de autocarga.
Eliminar todos los require_dependency y asegurarse de que el proyecto funcione correctamente.
Eliminar todos los require y asegurarse de que Discourse funcione correctamente.
Asegurarse de que todos los plugins puedan acceder a las dependencias requeridas. Aún no sé cómo lograrlo. Quiero primero hacer que Discourse funcione sin ningún plugin.
Por supuesto, aún quedan muchas incógnitas por resolver. Mantendré informados sobre el progreso; sin embargo, si están interesados en echar un vistazo, comencé a experimentar con esto aquí: Commits · KrisKotlarek/discourse · GitHub
Por favor, háganme saber si ven alguna desventaja al implementar Zeitwerk o si creen que me he olvidado de algo.
I made some progress around Zeitwerk, however, I changed my approach. My original plan was to change every place where Discourse is not following the Zeitwerk filename convention. After a few fixes, I realised that this is just the tip of the iceberg and noticed that if I am going to follow that path, then pull request will be difficult to read and confidently merge to master. For example, all job classes under regular directory should have Regular namespace, same with Onceoff and Scheduled.
I decided to step back a little bit and think about a more evolutionary approach than revolutionary.
I decided that it would be better to introduce custom Inflector, which will cover all files which are not following Zeitwerk convention. The biggest benefit will be that we would be able to deploy that small change and once we are happy with Zeitwerk and we don’t have any performance downgrades, we can start fixing convention file by file in reasonable small pull requests.
I found some problems which could not be sorted by custom Inflector, so I made additional fixes to make it work.
Pull request is still in progress, however, at this stage, I can run Discourse with Zeitwerk and default plugins, run all specs and run benchmark without a problem.
I wanted first to be at that stable state when all specs are passing. Now I can confidently start removing all require_dependency one by one and also test official plugins. Once everything is ready, I will share with you benchmark results in this post.
We can try another way to benchmark. What would you say about more iterations, something which would run for an hour? In addition, instead of taking the best result, compare the average from each experiment. That may give more consistent numbers. What do you think?
@sam I think we are good to go, I rebased with the latest master and made a small adjustment to Webauthn.
I checked 3 things:
run the server on local and click a little bit to ensure it works as expected
run specs
downloaded all official plugins and ensured that specs for plugins are passing (we need to merge adjustments for plugins first)