Recently I've been working with a few unusual issues with missing labels, in various different circumstances, one of these lead me to investigate label flushing - this is the process which takes newly created labels and moves them into the actual label files (*.ald files). This investigation was based on detailed analysis and live debugging of the AX kernel code whilst performing various label related operations, so I hope it can provide some insight into some of the stranger label related issues that might crop up occasionally.
The basic principle of label flushing is that when new labels are created they are written to a temporary label file, an *.alt file in the application folder. There is one alt file for each language. At certain points we will flush the labels from the alt file back to the actual label file, the *.ald file.
It is possible for newly created labels to appear blank for some users if the labels are flushed back to the *.ald file while the user is logged in. This is language specific, so if we flush back the en-us labels, and a user its logged in using en-us language, then that user may see blank labels, but other users with other languages will be ok. This is because the user is still trying to use an en-us label cache which is now invalid because of the flush.
There are two basic places where label files may be flushed, one is running Classes\Label::Flush(), the other is when disposing of a kernel label object which is instantiated inside Classes\Label (so when Classes\label is disposed we dispose this kernel object too). Of course disposing of Classes\Label can happen at many different times. Also Classes\Syslabel, because it extends Classes\Label, will cause the same thing.
The flush from label::flush() is a soft flush – it creates entries in the *.ald files but it does not remove flushed entries from alt file.
The flush when disposing of Classes\Label is a hard flush, this create entries in the *ald files and it removes entries from the alt file.
So there are a couple of main places where we dispose of Classes\Label:
- Restarting an AOS
- Closing the label editor
- Checking in an object with VCS.
I have found that the new labels for a particular language are flushed only when the last instance of the kernel label class relating to that language is disposed of in the AOS memory.
• Each user logged in will have one instance of this class instantiated with their language from user options when they log into the client.
• When opening the label editor we instantiate an instance of the label class for every language. When you close the label editor all languages which no other logged on user has instantiated are flushed back to the ald.
• If any user has a particular language instantiated then it will not be flushed to the ald.
• Each AOS service makes it's own decision about which languages to flush - each AOS does not know which languages the other AOS(s) are using.
• If a language which a user is using is flushed back to ald, then the new labels will appear blank for that user until the AOS is restarted.
So in a multi-AOS development environment we might have a problem where one AOS flushes labels but the other AOS has users logged on which are not ready for the flush to happen, causing those users to see blank labels. We can prevent labels from being flushed until the AOS restarts, and so prevent the problem where labels might appear blank for a user, by making sure we have each language that we need to protect instantiated on each AOS, so for example I have an environment where the languages in use are de-at, de, en-gb and en-us, so:
If I add some extra declarations to Classes\Application.ClassDeclaration() like this:
Then I add some extra code to Classes\Application.new() so that we instantiate the languages once in the AOS session (debugging this I see we actually instantiate twice in each AOS session, but that doesn't seem to cause a problem):
If(session.clientKind() == ClientType::Server)
label_deAt = new label('fr');
label_de = new label('de');
label_enGb = new label('en-gb');
label_enUs = new label('en-us');
Now when labels are flushed these languages will be protected, only flushing back to the ald files when one of the AOS is restarted. So one situation remains which could cause labels to appear missing, if one of the AOS is restarted it will flush the labels, and so users on the other AOS could potentially see blanks for new labels in their master language, to prevent this try to only restart AOSes at the same time when labels are being created in that environment.