The rationale behind this was to have a tight control over what code gets invoked from a finalize function. Using actor would also work, but given the higher risk code path of being called from the finalize function (RDD.finalize --> RDD.cleanup --> ContextCleaner.cleadRDD --> enqueue RDD ID in the queue), I think its better to use more easily understandable components.