OrchardCMS / Orchard

Orchard is a free, open source, community-focused Content Management System built on the ASP.NET MVC platform.
https://orchardproject.net
BSD 3-Clause "New" or "Revised" License
2.37k stars 1.12k forks source link

Any recommendation on the expected behavior when the dependent module is not installed? #8267

Open michaelsync opened 5 years ago

michaelsync commented 5 years ago

Hello,

We are using Orchard 1.10.1. We found three different behaviors when we have the modules that have the missing dependency.

let's say the module-A is depending on the module-B.

  1. Enabling the module after installing that module: I installed the module-A from the Gallery. It was successfully installed and asked me to enable it. So I clicked on the "Enable" button. It gave me "the object reference not set" error. Sometimes, the app pool restarts automatically and the website goes down. And the default shell is not loading back.

  2. Enabling the module from the module page: In the module listing page, it shows the missing dependency and it didn't let users enable it. I think it's the correct behavior.

  3. Restarting the site with the module that has the missing dependency: Let's say the dependent module (the module-B in this case) is removed/deleted/uninstalled for some reasons. But the module-A is still in the system. When we restart the IIS, the whole website doesn't load anymore because the Orchard framework is trying to start the module-A but got the error because the module-B is missing. but the framework kept on starting that problematic module-A again and again so the default shell can't be loaded.

Do we have any standard behavior what should happen when the module is missing the dependencies?

Skrypt commented 5 years ago

That generally means the module needs to be fixed. I think you found exactly why most people are not using the Gallery in 01. What you are experiencing is Dynamic Compilation issues which got fixed by not having it in Orchard Core 😉

michaelsync commented 5 years ago

Thanks. We are not ready to upgrade to Orchard Core. We have a lot of modules that we managed using the Gallery.

Edit: Please note that our modules are already compiled and it is in NuGet. So we just need to integrate our modules at runtime.

Is there any way to disable that Dynamic Compilation? Or Is there any replacement or alternative that I can use instead of Gallery?

Skrypt commented 5 years ago

If you only need to do dynamic loading of assemblies then the issue might still happen. Yes, there is a way to disable dynamic compilation from web.config file if I remember well. Though, best way to deploy is to use a CI to avoid these type of scenarios.

michaelsync commented 5 years ago

there is a way to disable dynamic compilation from web.config

Sure. I will check it out.

best way to deploy is to use a CI to avoid these type of scenarios

We are using CI as well. We have two parts (Orchard Website and Modules). We deploy the Orchard website from CI. But For modules, we publish them to our private NuGet. And then we upgrade those modules from Orchard gallery. We have the auto-upgrade and manual upgrade option.

If you are talking about deploying Orchard + modules together whenever we have a new release for one of our module, I don't think this is something that I want to do.

Skrypt commented 5 years ago

It's fine, everyone has their preferences 😉

michaelsync commented 5 years ago

:) True.

but I am new to Orchard. We are experiencing a lot of weird issues with loading, unloading module and dependencies. I am looking for a recommendation.

We are using Orchard for module development, configuration management but we are not using the CMS feature. We have different teams working on different modules. We have 3-4 releases a day. We have around 100 modules running. We have multi-tenants. We are hosting on Azure Web app. We are not able to move to Orchard Core yet.

What is the recommended way for us to do to avoid crashing down the whole site when one module is missing the dependency? or any recommended way to have the standard way of getting the same behavior when the dependent module is missing?

Skrypt commented 5 years ago

I used to have a staging Azure free Web app to test my modules before loading them on the prod server. But that implicates that this "staging" server should be a perfect replication of the production server which can be quite tricky.

Other though for the future. We might be able to use Docker for testing/deploying if Orchard 1 gets migrated to .NET 5.0 but that's a year from now still. Your best bet which will not be a perfect solution is the Azure Web App staging server. You could also try Azure Web App slots but I never tried to be honest.

Also, the issue with the dynamic loading of assemblies is that it's not perfect either because we can't unload an assembly from the runtime. Which means that if an updated module requires version 1.1 of a library that is already loaded by Orchard it can't load it without requiring reloading the application pool which can cause website interruptions. The Azure Web App slots are supposed to mitigate this behavior by pre-warming the next deployed website before swapping it as the online version.

BenedekFarkas commented 5 years ago

There were several changes in the past that broke Dynamic Compilation due to the lack of testing (we even have SpecFlow tests for those btw), which is quite unfortunate, because it's a huge productivity boost during development. But it's fixed for Orchard 1.10.3 (so it's OK on the current 1.10.x and dev branches too) and works with modules installed from the Gallery.

But as @Skrypt said, you're better off pre-compiling everything when you run Orchard - Dynamic Compilation is rather a developer feature. Also, the Gallery is nice to have, you can test a couple things that way, but most modules are not up2date, so eventually you'll run into issues.

In case you don't want to use DC, you can disable the DynamicExtensionLoader in HostComponents.config.

sebastienros commented 5 years ago

Agreed, don't use dynamic compilation on prod.

Also in your first comment, "1-" is an issue, it should not let you enable the feature.

michaelsync commented 5 years ago

Yes. I've checked our setting and I found that we are not using dynamic compilation.

All of our modules are compiled and packed as NuGet packages. But we still need to use Gallery to install/uninstall the module and its dependencies. So we sill need to load the dll on the fly.

This is where I found the different behaviors for loading/unloading the module at runtime.

BenedekFarkas commented 5 years ago

@michaelsync can you tell us more about this use-case? When you're running anything in Production, you should definitely have a precompiled application (including your dependencies as source beforehand for example) to avoid performance and security issues. You might be looking at an incompatibility between module/DLL versions.

lbcsy commented 4 years ago

one use case is: Module B depends on module A by specifying in B's module.txt, but it doesn't stop you to just install B from the gallery, and sometime later, the web server may not be able to restarted due to the dependency broken, thus you have no chance to install A at all.