<commit_before># Client Side

The following is an overview of the client side API.

## Creating a remote control

Instances of the `groovyx.remote.client.RemoteControl` class are used by clients to send closures to servers. This class has the following constructors…

    RemoteControl(groovyx.remote.client.Transport transport)
    RemoteControl(groovyx.remote.client.Transport transport, ClassLoader classLoader)

The `Transport` object is responsible for providing the means of communication with the server. The different transport jars (such as `remote-transport-http`) provide implementations of this interface. 

The classloader given to the constructor is used to find the `.class` files of the closures to be remotely executed. This means that the classloader must have access to the closure classes. The constructor variant with no classloader parameter implicitly uses the current thread's context class loader.

> The remote execution mechanism works by sending the definition of the closure class to the server. It does this by finding the corresponding `.class` file for the closure on the class path. This means that there must be a `.class` file for the closure on the class path for the closure to be able to be remotely executed. Closure's whose class has been generated dynamically at runtime are currently not supported.

## Execution

Remote control objects provide the following method for executing closures remotely…

    def exec(Closure[] commands)

It takes multiple closures to facilitate command *chaining* which will be discussed later.

Given a `RemoteControl` object named `remote`, the following would fetch the date/time on the server.

    def serverDate = remote.exec { new Date() }

This will cause the given closure to be sent to the server (via the remote's `Transport` object) and executed there. The result of the closure is then sent back to the client and returned as the return of the `exec()` method call.

### Closure delegate, owner and thisObject

When the closure is sent to the server, its `delegate`, `owner` and `thisObject` are all set to `null`. This is done to minimise what needs to be serialised and to reduce issues any of these objects being unserialisable or having references to objects that are unserialisable.

However, when the closure is executed on the server side its delegate is set to what is called the command *context*. See the section on [contexts](contexts) for more information.

### Chaining

Muliple commands can be *chained* together. They are executed serially in order, with the result of the previous command being passed as the only argument to the next command in the chain. The only exception to this is when the next closure does not take any arguments. In this case the result of the previous command is simply discarded.

    assert remote.exec({ 1 }, { it + 1 }, { it + 1 }) == 3

### Currying

It's also possible to send curried closures.

    assert remote.exec({ it + 2 }.curry(2)) == 4

You can also used curried closures in chains.

    assert remote.exec({ 2 }, { num, previous -> num + previous }.curry(10)) == 12

Curry parameters must be serializable. If they are not, a `java.io.NotSerializableException` will be thrown on the client side.

### Inner Closures

You can use closures inside the command closure.

    remote.exec {
        def total = 0
        [1, 2, 3, 4].each {
            total += it
        }
    }

### Adding closures to context

Sometimes you might want to define closures outside of the `exec` method call and then execute them on the server side. This is especially usefull when creating DSL-like calls that get executed on the remote. You can use `usedClosures` option in the `exec` call for that.

Given a delegate class and a dsl entry-point:

    class DslDelegate {
        int value

        void startingWith(int value) {
            this.value = value
        }

        void add(int added) {
            value += added
        }

        void subtract(int subtracted) {
            value -= subtracted
        }

        void divideBy(int dividedBy) {
            value /= dividedBy
        }
    }

    void dsl(Closure closure) {
        remote.exec(usedClosures: [closure]) {
            def dslDelegate = new DslDelegate()
            closure.setDelegate(dslDelegate)
            closure.call()
            dslDelegate.value
        }
    }<commit_msg>More explanation on why usedClosures exec option is needed in the docs<commit_after># Client Side

The following is an overview of the client side API.

## Creating a remote control

Instances of the `groovyx.remote.client.RemoteControl` class are used by clients to send closures to servers. This class has the following constructors…

    RemoteControl(groovyx.remote.client.Transport transport)
    RemoteControl(groovyx.remote.client.Transport transport, ClassLoader classLoader)

The `Transport` object is responsible for providing the means of communication with the server. The different transport jars (such as `remote-transport-http`) provide implementations of this interface. 

The classloader given to the constructor is used to find the `.class` files of the closures to be remotely executed. This means that the classloader must have access to the closure classes. The constructor variant with no classloader parameter implicitly uses the current thread's context class loader.

> The remote execution mechanism works by sending the definition of the closure class to the server. It does this by finding the corresponding `.class` file for the closure on the class path. This means that there must be a `.class` file for the closure on the class path for the closure to be able to be remotely executed. Closure's whose class has been generated dynamically at runtime are currently not supported.

## Execution

Remote control objects provide the following method for executing closures remotely…

    def exec(Closure[] commands)

It takes multiple closures to facilitate command *chaining* which will be discussed later.

Given a `RemoteControl` object named `remote`, the following would fetch the date/time on the server.

    def serverDate = remote.exec { new Date() }

This will cause the given closure to be sent to the server (via the remote's `Transport` object) and executed there. The result of the closure is then sent back to the client and returned as the return of the `exec()` method call.

### Closure delegate, owner and thisObject

When the closure is sent to the server, its `delegate`, `owner` and `thisObject` are all set to `null`. This is done to minimise what needs to be serialised and to reduce issues any of these objects being unserialisable or having references to objects that are unserialisable.

However, when the closure is executed on the server side its delegate is set to what is called the command *context*. See the section on [contexts](contexts) for more information.

### Chaining

Muliple commands can be *chained* together. They are executed serially in order, with the result of the previous command being passed as the only argument to the next command in the chain. The only exception to this is when the next closure does not take any arguments. In this case the result of the previous command is simply discarded.

    assert remote.exec({ 1 }, { it + 1 }, { it + 1 }) == 3

### Currying

It's also possible to send curried closures.

    assert remote.exec({ it + 2 }.curry(2)) == 4

You can also used curried closures in chains.

    assert remote.exec({ 2 }, { num, previous -> num + previous }.curry(10)) == 12

Curry parameters must be serializable. If they are not, a `java.io.NotSerializableException` will be thrown on the client side.

### Inner Closures

You can use closures inside the command closure.

    remote.exec {
        def total = 0
        [1, 2, 3, 4].each {
            total += it
        }
    }

### Passing additional closures to the server side

When using the library you have to be aware that only the closure defined in `exec` call and closures defined within that closure are serialized and passed to the server side. Sometimes you might want to define closures outside of the `exec` method call and then execute them on the server side. This is especially useful when creating DSL-like calls that get executed on the remote. You can use `usedClosures` option in the `exec` call for that.

Given a delegate class and a dsl entry-point:

    class DslDelegate {
        int value

        void startingWith(int value) {
            this.value = value
        }

        void add(int added) {
            value += added
        }

        void subtract(int subtracted) {
            value -= subtracted
        }

        void divideBy(int dividedBy) {
            value /= dividedBy
        }
    }

    void dsl(Closure closure) {
        remote.exec(usedClosures: [closure]) {
            def dslDelegate = new DslDelegate()
            closure.setDelegate(dslDelegate)
            closure.call()
            dslDelegate.value
        }
    }
{'fraction_non_alphanumeric': 0.057930881701373504, 'fraction_numerical': 0.0037660611431103233, 'mean_word_length': 3.347135291285508, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1542685', 'n_tokens_mistral': 2290, 'n_tokens_neox': 2142, 'n_words': 1221}