Today I was asked by my colleague something on the lines “Do I need to restart K2 host server service if I added “NewtonJson.dll into GAC?”
This is quite an interesting question which I would re-phrase as “Do I need to restart K2 host server service if I added DLL X in location Y?” Unfortunately there is no easy answer, though you may assume that developer should know this for sure. That’s a bit of a myth that “developer as a creator of a program can predict any output from the app for any given input”, and explanation to that phenomenon has surprising parallels with much sought after in middle ages explanation of “how is free will possible in the light of the fact that there is an almighty and all knowing creator in this universe”, buy I guess I will save this philosophical topic for separate blog post.
I’ve split this question into some sub-questions and checked with one of the developers (only to confirm all that was said above).
How K2 service loads DLLs?
It all differs from DLL to DLL.
Little clarification (as I was pointed out that I’m using outdated terminology): DLL stand’s for Dynamic-Link Library and I employ it to refer to any files with DLL extension since my DOS gaming days, whereas modern official term commonly used by developers is assembly. Term comes from the new Global Assembly Cache (GAC) infrastructure. This is machine-wide CLI assembly cache for the Common Language Infrastructure (CLI) in .NET Framewrok, which was designed to allow for specially controlled central repository which addresses the flaws of the shared library concept and helps to avoid DLL hell.
Getting back to the question above: some assemblies we may load in memory on startup and keep there till service restart, but some may be called as needed an then disposed (though again you can’t easily tell when they are disposed, except for service restart). Among those which “load on demand” some loaded by K2 service while others are loaded automatically by .NET. But we have two GAC repositories on modern Windows platform one for .NET v2 and another for .NET v4 and sometimes the same assembly exist in two versions and which one called depends on your application code.
As you can see things can be quite different and it all depends.
Just to illustrate: I remember an issue which may be reproduced in old (pre-4.7) versions of K2 when you erroneously place to GAC SourceCode.Workflow.Resolver.Data.dll. It should not be there in the first place, but if you place it there it is trying to call another DLLs (SourceCode.Workflow.Functions.dll) from current directory as both of them exist in K2 bin folder. Yet as soon as 1st DLL landed to GAC it takes priority over one from the Bin folder, but then errors out as it can’t see 2nd DLL in GAC. So on versions prior to 4.7 workflow will enter into Error state with the following error logged in Error profiles: Assembly ‘SourceCode.Workflow.Functions’ could not be found. In 4.7 workflow will enter into Error state with more actionable error message: “Please remove SourceCode.Workflow.Data.Resolvers from the Global Assembly Cache.”
Do I need to do K2 restart after I GACed NewtonJson.dll, for example?
Probably. NewtonJson.dll is a 3rd party dll K2 uses for JSON serialization and some other things. And whether restart is needed depends on what K2 DLL is using it, but the safest option is always perform a restart of the service. Even IIS sometimes keep a cached copy, and does not use the new one if you replace it until iisreset is performed.
Is there some (relatively) easy way to tell which DLLs can be safely replaced without K2 service restart?
Here we can think that some debug utilities should exist which may tell you which assemblies are used by specific process. I don’t know any of the top of my head and have to reseatch this separately. Normally, if you can overwrite the file, then it already means it is not being used at the moment. But, for example, IIS is different, as it keeps a cached copy in a temp folder somewhere. So it all depends on how specific DLL is loaded/used by each specific service – it may be loaded in memory or some sort of cache hence there is no easy way to determine if service restart is necessary after file replacement. Safe bet in most of the cases, is to perform a K2 service restart.
Just decided it is worth taking a note of this and share with other people who may potentially have similar questions.