Putting non linear optimization in a real-time closed-loop

Try printing something after the call to sleep and you’ll notice that it does in fact sleep. The @async causes start_optimization_process to return immediately, what you are missing is probably that at some point you need to wait on the task returned by the @async call, something like this

opt_task = start_optimization_process(...)
...
wait(opt_task)

Note, though, that @async does not cause things to run in parallel, for that, you instead want Threads.@spawn. Also note the warning

help?> @async
  @async

  Wrap an expression in a Task and add it to the local machine's scheduler queue.

...

  │ Warning
  │
  │  It is strongly encouraged to favor Threads.@spawn over @async always even when no parallelism
  │  is required especially in publicly distributed libraries. This is because a use of @async
  │  disables the migration of the parent task across worker threads in the current implementation
  │  of Julia. Thus, seemingly innocent use of @async in a library function can have a large
  │  impact on the performance of very different parts of user applications.