---
title: Apache Celix Events
---

<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at
   
    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

# Apache Celix Scheduled Events

Apache Celix provides supports to schedule events on the Apache Celix Event Thread. This allows users to 
reuse the existing Apache Celix events thread to do tasks on the event thread.

Scheduled events will be called repeatedly using a provided interval or once if 
only an initial delay is provided. For the interval time, a monotonic clock is used.

The event callback should be relatively fast, and the scheduled event interval should be relatively high; otherwise, 
the framework event queue will be blocked, and the framework will not function properly. 
Network IO should not be done in the event callback, but instead, a separate thread should be used for this.

## Scheduling an Event

To schedule an event in the Apache Celix framework, use the `celix_bundleContext_scheduleEvent` C function or 
`celix::BundleContext::scheduleEvent` C++ method. For C, an options struct is used to configure the scheduled event, 
and for C++, a builder pattern is used to configure the scheduled event.

### C Example

```c
#include <stdio.h>
#include <celix_bundle_activator.h>

typedef struct schedule_events_bundle_activator_data {
    celix_bundle_context_t* ctx;
    long scheduledEventId;
} schedule_events_bundle_activator_data_t;

void scheduleEventsBundle_oneShot(void* data) {
    schedule_events_bundle_activator_data_t* act = data;
    celix_bundleContext_log(act->ctx, CELIX_LOG_LEVEL_INFO, "One shot scheduled event fired");
}

void scheduleEventsBundle_process(void* data) {
    schedule_events_bundle_activator_data_t* act = data;
    celix_bundleContext_log(act->ctx, CELIX_LOG_LEVEL_INFO, "Recurring scheduled event fired");
}

static celix_status_t scheduleEventsBundle_start(schedule_events_bundle_activator_data_t *data, celix_bundle_context_t *ctx) {
    data->ctx = ctx;

    //schedule recurring event
    {
        celix_scheduled_event_options_t opts = CELIX_EMPTY_SCHEDULED_EVENT_OPTIONS;
        opts.name = "recurring scheduled event example";
        opts.initialDelayInSeconds = 0.1;
        opts.intervalInSeconds = 1.0;
        opts.callbackData = data;
        opts.callback = scheduleEventsBundle_process;
        data->scheduledEventId = celix_bundleContext_scheduleEvent(ctx, &opts);
    }

    //schedule one time event
    {
        celix_scheduled_event_options_t opts = CELIX_EMPTY_SCHEDULED_EVENT_OPTIONS;
        opts.name = "one shot scheduled event example";
        opts.initialDelayInSeconds = 0.1;
        opts.callbackData = data;
        opts.callback = scheduleEventsBundle_oneShot;
        celix_bundleContext_scheduleEvent(ctx, &opts);
    }

    return CELIX_SUCCESS;
}

static celix_status_t scheduleEventsBundle_stop(schedule_events_bundle_activator_data_t *data, celix_bundle_context_t *ctx) {
    celix_bundleContext_removeScheduledEvent(ctx, data->scheduledEventId);
    return CELIX_SUCCESS;
}

CELIX_GEN_BUNDLE_ACTIVATOR(schedule_events_bundle_activator_data_t, scheduleEventsBundle_start, scheduleEventsBundle_stop)
```

### C++ Example

```cpp
#include <iostream>
#include "celix/BundleActivator.h"

class ScheduleEventsBundleActivator {
public:
    explicit ScheduleEventsBundleActivator(const std::shared_ptr<celix::BundleContext>& ctx) {
        //schedule recurring event
        event = ctx->scheduledEvent()
                .withInitialDelay(std::chrono::milliseconds{10})
                .withInterval(std::chrono::seconds{1})
                .withCallback([ctx] {
                    ctx->logInfo("Recurring scheduled event fired");
                })
                .build();

        //schedule one time event
        ctx->scheduledEvent()
                .withInitialDelay(std::chrono::milliseconds{10})
                .withCallback([ctx] {
                    ctx->logInfo("One shot scheduled event fired");
                })
                .build();
    }

    ~ScheduleEventsBundleActivator() noexcept {
        std::cout << "Goodbye world" << std::endl;
    }
private:
    celix::ScheduledEvent event{};
};

CELIX_GEN_CXX_BUNDLE_ACTIVATOR(ScheduleEventsBundleActivator)
```

## Waking up a Scheduled Event

To process a scheduled event directly, you can use the `celix_bundleContext_wakeupScheduledEvent` C function or 
`celix::ScheduledEvent::wakup` C++ method. This will wake up the scheduled event and call its callback function.
