WorkerAPI - Communicating out


(Jason Griffith) #1

Hello everyone!

I’m starting to play with the Worker API, and I have a question about the best way to send information from the workers up to the Task that kicked them off… Or if that’s even what I ought to do.

Here’s a stripped-down example. The work-unit has some information to make available to other tasks/projects/antmen. What’s the right way?

I should add this is a code plugin, not a script plugin, so I don’t have access to the script builtin variables.

I tried passing the Project into the Runnable, but that fails with “org.gradle.workers.internal.ActionExecutionSpec$ParameterSerializationException: Could not serialize parameters”

@CompileStatic
public class NeatoTasko extends DefaultTask {
    final WorkerExecutor workerExecutor
    String someInput

    @Inject
    public NeatoTasko(WorkerExecutor workerExecutor) { this.workerExecutor = workerExecutor }

    @TaskAction
    public void exec() {
        getProject().getLogger().quiet("This is some logging stuff!")
        workerExecutor.submit(NeatoExecutor.class) { WorkerConfiguration config ->
            config.isolationMode = IsolationMode.NONE 
            config.params someInput
        }
    }
}

public class NeatoExecutor implements Runnable {
    String frobozz

    @Inject
    public NeatoExecutor(String frobozz) {
        this.frobozz = frobozz
    }

    @Override
    void run() {
        // !!! vvv-- Pretend this is the info we want to bubble up and out somehow 
        return "$frobozz $frobozz"
    }
}

Thanks!


(Stefan Oehme) #2

Sending information back is not supported at the moment. Of course you could write things to a file, but it would be intersting to first know what your use case is.


(Jason Griffith) #3

Hi Stefan,

Our current usecase is we’re mid-Gradlification of an existing build system where we’d kick off a few subprocesses in one task and manipulate/shred/store the output in another. We can use files for this as you say, but was hoping to have something a little more direct. No biggie; we may just have some additional refactoring to do in where that processing happens.

Another question: For logging within the Runnable, what’s the correct way to acquire a Gradle Logger? https://docs.gradle.org/4.0/javadoc/org/gradle/api/logging/Logger.html says to use Project.getLogger() or Task.getLogger(), but those aren’t available to our Runnables. Passing the Logger in from the outside leads to a serialization exception.

Thanks!


(Stefan Oehme) #4

There is no way to inject the logger yet, though you can use slf4j for instance and Gradle will bridge it. In future releases we will allow injection of several services. Logging will be among them.

Generally I’d either use files (if creation and consumption of the information are far apart) or move the processing closer together, e.g. in the same runnable. A big risk of keeping state in tasks is that it bloats memory consumption and it’s easy to forget to null out that state when it’s no longer needed. If the state stays only within a single work item, there is a nice boundary to its lifetime.


(Jason Griffith) #5

Thanks! Is there a way to get the project object from within the Runnable or is that one of the future to-be-injecteds?


(Stefan Oehme) #6

The mutable project object will never be available, as that would break parallel safety. However, many of the services that Project currently provides will be injectable


(Jason Griffith) #7

Cool. Thanks for the information!


(Jeffl Newhope) #8

@st_oehme Since I’m trying the first time to get the Worker API running I’m currently struggeling with a comparable problem. We wrote a custom Logger Class in our company, which I’d like to use in the runnable but unfortunately I can’t pass the logger into the Runnable. Is the only way to log this stuff to write it in the Runnable in a file and after completion of the Runnable log it in the task?


(Stefan Oehme) #9

For now that’s the best option I can think of, yes.