2

Spring Boot app, where Spring Boot's scheduled method calls RX method (rxjava3) to do the long job (in separate thread pool).

@Scheduled(fixedDelay = ONE_SECOND)
public void init() {

    process().subscribe(); // it returns Disposable
}

Imagine if process() takes more than 1 second to finish, then the Disposable (that process returns) stays "flying in the air" and could be destroyed by GC, and the process() operation could be destroyed as well? (question 1)

I wonder what is the safe or standard approach. If one got similar worries.

(I do not want to use Job annotations or Quartz for that)

Sure, I can do process().blockingGet(), but that would block my main thread, and possibly interfere with @Scheduled (not sure). So I want to be explicit - saying: "hey, I am not blocking anything, just launching the processes here."

var disposable = process().subscribe()

this.processDisposables.add(disposable) - would this do the trick?

This way my Spring service would always have a link to disposable. So GC would not dare to collect? (question 2)

But then I could end up having infinite amount of those links in that list. And would need to think about cleaning them. (and maybe can lead to memory leaks)

Let me know what you think. Is there a better approach? (question 3)

update (to save on comments):

yes I, "want a process that lasts more than 1 second to complete and then be disposed"

ses
  • 13,174
  • 31
  • 123
  • 226
  • I don't know the answer but this is a good question. I am interested as well as I need to create similar tasks in the future for an application I will be working on. – hfontanez Jan 12 '22 at 16:29
  • 1
    Do you actually have proof that the garbage collector "destroys" your Disposable (e.g. in the form of a [mre]), or are you just guessing? – Mark Rotteveel Jan 12 '22 at 16:31
  • @MarkRotteveel guessing for now. will test it. but .. this kind of testing is time consuming. but necessary anyways. GC/MemoryLeaks etc. (plus I know there are some bits on how to connect "properly" spring boot and rx java, that may "take care" of it, as tuned settings (explicitly)). The "guess" part maybe a cause ppl to vote to "close" this question, yet, I think SO would benefit if ppl would ask theme self this question while connecting rx with spring boot. (not using spring boot reactor as default rx extension) – ses Jan 12 '22 at 16:41
  • do you want a process that lasts more than 1 second to complete and then be disposed (which would be the default here), or you want to cancel it when a new one is created? – Francesco Rogo Jan 12 '22 at 17:07
  • 2
    You are trying to fix an artificial problem constructed with a fundamentally wrong understanding of garbage collection. If `process()` returns an object, the garbage collector will never “destroy” that object. Just think about it: why would anyone implement a programming language with a garbage collector that creates the very problem it is supposed to solve? The whole point of garbage collection is to ensure that you can never free the memory of an object that is still in use. – Holger Jan 12 '22 at 17:16
  • what process() returns is not in use, once init() method ends – ses Jan 12 '22 at 18:34
  • 1
    You wrote "if process() takes more than 1 second to finish" and of course, `init()` does not return before `process()` returns. Even with asynchronous operations, there are only two possibilities. Either, the object is in use or its collection makes no difference. – Holger Jan 12 '22 at 19:09
  • 4
    The `Disposable` won't get garbage collected until the Rx chain completes or is disposed, so you don't have to do anything. Once `init` exits, it is true that the local reference to the `Disposable` returned by the `subscribe` call goes out of scope, but the upstream Rx operator will still hold a reference to it. That operator will be referenced by the operator upstream from it, etc. Eventually you hit some code that is actively running in a thread somewhere, or referenced by an RxJava scheduler, so the whole chain is kept alive. – dano Jan 12 '22 at 20:41

0 Answers0