Ask Reuben
Deploying Individual .42m
I have made a fix to single .4gl, can I deploy that single .42m? or do I have to deploy my whole application?
What changes can I made to a .4gl and not have to worry about redeploying my whole application?
“DON’T”, that should be the one word answer to deploying individual .42m files, but there are times when you can consider it or perhaps may need to do it.
The question arises when a change is made to a single .4gl file and the developer asks themselves, “can I compile this .4gl to produce a .42m, and deploy this .42m into my binaries area without having to recompile and redeploy my entire application?”
Typically this is because the change is minor, that is a spelling error, a minor logic fix such as changing a > to a >=, changing the case of an expression, widening a field in a report, adding or removing an attribute etc. There may also be an element of urgency that precludes you doing a full recompile and deployment, for instance someone is about to do a sales demonstration and has noticed an issue at the last minute. Finally the destination is typically not to a live production but to an internal system, wether sales, training, QA etc
We have different types of customers. ISV’s who produce an application that are used by many different customers, Enterprise customers code and use their own Genero application, and a Service Providers who maintain a Genero application on behalf of an end-user. It is interesting the different strategies and standards these different types of customers adopt. An ISV might consider deploying an individual .42m into production abhorrent and something they would never consider, but it might be something an Enterprise customer does from time to time when their enterprise needs it.
An analogy to take into the decision making is to compare a .42m to a piece of a jigsaw puzzle. You can replace the piece as long as the bits where it touches the rest of the jigsaw puzzle don’t change.
You have to consider wether you are linking (that is producing a .42r) or 100% using IMPORT FGL (that is no .42r).
When linking and using a .42r, it helps to have an understanding of what is in a .42r contains and does. If you use od -c
on a .42r you will see it is a list of function names and modules names. All the code logic is inside a .42m (a common misconception is that the .42r contains the logic). When fglrun is executing and it comes to a CALL, it looks to see if the called function is inside the current .42m, if not it looks inside the .42r to see what .42m the called function is in and it loads that particular .42m using FGLLDPATH to find it. So if the change you make to a .4gl would result in the compiled .42r being different then it is not safe to deploy the resulting .42m. That can include …
- calling a function in a different .42m that is not called by the program currently
- renaming a function that is called from another module
- changing the number of arguments to/from an external function
- etc
That list is not exhaustive, but what you can hopefully can see is that changes such as correcting a spelling error, correcting minor logic don’t have any impact on a .42r.
The introduction of IMPORT FGL adds some complexity but at the same time removes some complexity.
It removes some complexity in that you no longer need to link and produce a .42r, and you can simply run the .42m directly. i.e fglrun module.42m. When the runner is looking for a function in an external module, if you have CALL module.function() then it knows what .42m to load, or if you have CALL function() then it will iterate through the IMPORT FGL modules to figure out which .42m to load. So for the case of calling a function in a different .42m that has not been called before, if you have added an additional IMPORT FGL then the runner will know where to find and call that function.
With IMPORT FGL you have added complexity with PUBLIC TYPE, PUBLIC DEFINE. If you change the definition of these then you have to consider any child modules that are referencing these. For instance if you have a public type and references to it in child modules e.g.
#! module-name.4gl PUBLIC TYPE public-type-name ... #! child.4gl IMPORT FGL module-name DEFINE variable-name module-name.public-type-name
… or a public variable …
#! module-name.4gl PUBLIC DEFINE variable-name ... #! child.4gl IMPORT FGL module-name LET module-name.variable-name = ...
then these child modules need to be re-compiled in order to pick up the change in the parent module. The public type and variable definition is looked up and built into the compiled code at compile time, not at runtime. For those that are PRIVATE then you know changes are self-contained to that module.
Based on what you have learned above, it maybe that in order to deploy a particular .42m you also have to deploy at the same time an updated .42r or some additional .42m.
Finally in wrapping up you may have observed that in Genero Application Server in recent years we have added functionality that enables you to deploy applications. Read from here on deploying apps with Genero Archive. There is NO option in there to deploy individual .42m. Take that as a hint and also note my initial one word answer. However there are times when you may need to deploy an individual .42m file, it is possible providing you take into account the nature of the change and make sure any change is self-contained within that .42m.