# Scheduling

`Ecotone` comes with support for running `period tasks` or `cron jobs.`

## Scheduled Method

```php
class NotificationService
{
    #[Scheduled(endpointId: "notificationSender")]
    #[Poller(fixedRateInMilliseconds: 1000)]
    public function sendNotifications(): void
    {
        echo "Sending notifications...\n";
    }
}
```

`endpointId` - it's name which identifies process to run\
`poller` - Configuration how to execute this method [read more in next section](#polling-metadata).\
Above configuration tells `Ecotone` to execute this method every second.

{% tabs %}
{% tab title="Symfony" %}

```php
console ecotone:list
+--------------------+
| Endpoint Names     |
+--------------------+
| notificationSender |
+--------------------+
```

{% endtab %}

{% tab title="Laravel" %}

```php
artisan ecotone:list
+--------------------+
| Endpoint Names     |
+--------------------+
| notificationSender |
+--------------------+
```

{% endtab %}

{% tab title="Lite" %}

```php
$consumers = $messagingSystem->list()
```

{% endtab %}
{% endtabs %}

After setting up Scheduled endpoint we can run the endpoint:

{% tabs %}
{% tab title="Symfony" %}

```php
console ecotone:run notificationSender -vvv
```

{% endtab %}

{% tab title="Laravel" %}

```
artisan ecotone:run notificationSender -vvv
```

{% endtab %}

{% tab title="Lite" %}

```php
$messagingSystem->run("notificationSender");
```

{% endtab %}
{% endtabs %}

## Scheduled Handler

You can run `Scheduled` for given Handler.\
Right now method return [Message](https://docs.ecotone.tech/messaging/messaging-concepts/message) which is send to given routing.

```php
class CurrencyExchanger
{
    #[Scheduled(requestChannelName: "exchange", endpointId: "currencyExchanger")] 
    #[Poller(fixedRateInMilliseconds=1000)]
    public function callExchange() : array
    {
        return ["currency" => "EUR", "ratio" => 1.23];
    }
}

#[CommandHandler("exchange")] 
public function exchange(ExchangeCommand $command) : void;
```

`requestChannelName` - The channel name to which [Message](https://docs.ecotone.tech/messaging/messaging-concepts/message) should be send.

When the Message will arrive on the Command Handler it will be automatically converted to `ExchangeCommand.` If you want to understand how the conversion works, you may read about it in [Conversion section](https://docs.ecotone.tech/messaging/conversion).

## Expression Language

We can also set up cron and fixed rate using expression language. This gives us ability to set it up differently based on the environment we are currently in.

```php
class CurrencyExchanger
{
    #[Scheduled(requestChannelName: "exchange", endpointId: "currencyExchanger")] 
    #[Poller(fixedRateExpression="reference('timerService').getFixedRate()")]
    public function callExchange() : array
    {
        return ["currency" => "EUR", "ratio" => 1.23];
    }
}
```

{% hint style="success" %}
Timing will be evaluated once, and then preserved as timing configuration. The evaluation will happen when ecotone:run will be executed.
{% endhint %}

## Materials

### Demo implementation

You may find demo implementation [here](https://github.com/ecotoneframework/quickstart-examples/tree/main/Schedule).

### Links

* [Scheduling Execution in PHP](https://blog.ecotone.tech/scheduling-execution-in-php/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ecotone.tech/modelling/asynchronous-handling/scheduling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
