3

I am not sure if this is the right place to post this question, but I think this might be better suited than Stack Overflow.

I have got an online application, a Java EJB application. Requirement is to have an external configuration file which will contain property using which the application is going to decide whether or not to perform a business function.

We do not want to read this file everytime, we'll read this once, store the value and use the value until the content of file changes.

To handle this, I had two approaches,

  1. Have a file listener which would check the file and update the variables when the file changes

  2. Have a servlet to force Refresh from the file

Both of these are not approved. #1 would add to the processing time and #2 is a security violation as per their standards.

Now I am out of ideas, is there anyway I can have a file listener out of my actual processing, like in the application level and transaction? Is there another approach to implement this?

  • What do you mean by "#1 would trio processing time"? Is your configuration file that huge? What mechanism were you proposing to use to watch the file system for changes? – BobDalgleish Mar 7 at 20:09
  • @WhiteBird, when you say "trio processing time" are you saying it would take 3x the amount of time to process? If so, what's the baseline? Are we talking going from 1s to 3s or 10m to 30m? Finally, do you have a definition of acceptable processing time? – Berin Loritsch Mar 7 at 20:48
  • It might interest jndi. And this. Some containers allow you to set set the jndi cache too so that the changes on the remote file can be fetched inmediatly or after a while. – Laiv Mar 7 at 20:59
  • @BobDalgleish I meant "added to the", was a typo. And no config files arent going to be huge, would be just 2-3 entries at most. I was thinking of using thread polling to watch a file – WhiteBird Mar 8 at 2:59
  • @Berin Loritsch It was a typo, but we do have an acceptable total processing time for our app which is 1.5 seconds. Currently the app takes 1.3 on an average, while adding this particular config thing they need it to stay at 1.3, which means we have got 0.05 which is what they are looking at. Also they do not want this process of hot-reloading to be part of the transactional flow, but outside of it. In that case the time shouldnt matter. – WhiteBird Mar 8 at 3:02
0

I use these methods, 1 or 2 below in various projects.

1. Use java.nio.file.WatchService to wait for changes.

I guess this is what you mean by "a listener".

For the narrow scenario of tracking occasional changes to a few config files on Linux local filesystems (using Linux's inotify), this produces very quick updates (near instant from a user perspective) when a config file changes, with insignificant resources used, in my experience.

Linux's inotify is not a polling mechanism. It's a feature of the linux kernel that generates events when files change. Java has wrapped this with the WatchService. Windows has similar capabilities and I imagine your JDK/JVM will use them, but I have not tested it.

In my experience it does not take 3x time or cpu to track config local file changes in this way. But it's not perfect. In particular renaming of files and directories can be tricky (not part of my use scenarios) and inotify does not pick up change events on remote filesystems. WatchService falls back on other implementation (probably polling), which I have not used.

I can't swear to the implementation on every platform for every JDK. Test it.

2. Implement a simple form of lazy initialization with caching.

This produces reliable cheap updating when config files change, with a defined maximum delay period, like 30s.

  • For the first request read the file, save a timestamp.

  • For every subsequent request of the file's properties, check the timestamp.

  • If the data is older than your cache expiration time (say 30s or 1 minute), check the file's modify time and reread if needed.

Thread-Safe Access

For both approaches to share configuration across a busy multithreaded application, I use standard tools from java.util.concurrent to allow non-blocking reads of configuration. For Example:

  • Make the properties structure immutable. Share access to it through an AtomicReference<>. When you reread the config file make a new instance of your config properties and replace the old instance.

  • Or Use a ConcurrentHashMap referencing immutable objects, if the contents consist of an extensible number of different objects needing separate updating and key-value access. When rereading a config file, replace objects with new immutable instances.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.