Search code examples
juliaatexit

Julia's behaviour for atexit in module


Assume I have a module SomeModule.jl:

module SomeModule

export use_me

function use_me()
  println("I'm useful!")
end

function call_me_in_the_end()
  println("This is the end")
end

atexit(call_me_in_the_end)

end

And main.jl using this module:

import SomeModule: use_me

use_me()

Since function passed into atexit is called at process exit I expect to see when calling main.jl:

I'm useful!
This is the end

But instead I'm getting:

This is the end
I'm useful!

on the first call, and only:

I'm useful!

for all subsequent calls, until I make changes in SomeModule.jl. After changes are made everything repeats.

I've tried to bring atexit outside of the module, like so:

module SomeModule
  ...
end

import SomeModule: call_me_in_the_end

atexit(call_me_in_the_end)

but result is the same.

So, two questions:

  1. Why call_me_in_the_end is called only once and how to fix it?
  2. How to make call_me_in_the_end be called in the end?

Julia's version is 1.7.3 for macOS x86


Solution

  • The module gets compiled after the first run and hence the exit hook does not get attached in subsequent runs.

    Instead you should have used the special __init__ that gets executed whenever module gets loaded:

    module SomeModule
    
    function __init__()
      #this gets executed whenever using SomeModule is called regardless of precompilation
      println("Attaching the hook")
      atexit(call_me_in_the_end)
    end
    
    function call_me_in_the_end()
      println("This is the end")
    end
    
    end
    

    Regarding the output order this is just related to stream buffering and such behavior is observed quite often in multitask application. Simply add flush(stdout) after your last println statement in your code before exit() is called and you will be good.