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.