Event batching
This topic describes how the Optimizely Android SDK uses the event processor to batch impressions and conversion events into a single payload before sending it to Optimizely.
The Optimizely Full Stack Android SDK now batches impression and conversion events into a single payload before sending it to Optimizely. This is achieved through a new SDK component called the event processor.
Event batching has the advantage of reducing the number of outbound requests to Optimizely depending on how you define, configure, and use the event processor. It means less network traffic for the same number of Impression and conversion events tracked.
In the Android SDK, BatchEventProcessor
provides implementation of the EventProcessor
interface and batches events. You can control batching based on two parameters:
- Batch size – Defines the number of events that are batched together before sending to Optimizely.
- Flush interval – Defines the amount of time after which any batched events should be sent to passed to the Event Dispatcher to be sent to Optimizely.
An event consisting of the batched payload is sent as soon as the batch size reaches the specified limit or flush interval reaches the specified time limit. BatchEventProcessor
options are described in more detail below.
Note
The default Event Dispatcher in our Android SDK uses an Android Intent Service to dispatch batched requests. As a result, you may observe additional delays to outbound requests beyond your specified flush interval as a result of system limits on those requests.
Optimizely's Event batching works with both out-of-the-box and custom event dispatchers.
The event batching process does not remove any personally identifiable information (PII) from events. You must still ensure that you aren't sending any unnecessary PII to Optimizely.
Basic example
import com.optimizely.ab.android.sdk.OptimizelyManager;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
String sdkKey = "{SDK_KEY}";
OptimizelyManager optimizelyManager = OptimizelyManager.builder()
.withSDKKey(sdkKey)
.build(getApplicationContext());
Optimizely optimizely = optimizelyManager.initialize(MainActivity.this, R.raw.datafile);
}
}
By default, batch size is 10 and flush interval is 30 seconds.
Advanced example
import com.optimizely.ab.android.sdk.OptimizelyManager;
import com.optimizely.ab.android.sdk.OptimizelyClient;
import com.optimizely.ab.event.BatchEventProcessor;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
String sdkKey = "{SDK_KEY}";
EventHandler eventHandler = DefaultEventHandler.getInstance(context);
// Here we are using the builder options to set batch size
// to 5 events and flush interval to a minute.
BatchEventProcessor batchProcessor = BatchEventProcessor.builder()
.withBatchSize(5)
.withEventHandler(eventHandler)
.withFlushInterval(1, TimeUnit.MINUTES)
.build();
OptimizelyManager optimizelyManager = OptimizelyManager.builder()
.withSDKKey(sdkKey)
.withEventHandler(eventHandler)
.withDatafileDownloadInterval(15L, TimeUnit.MINUTES)
.withEventProcessor(batchProcessor)
.build(getApplicationContext());
OptimizelyClient optimizely = optimizelyManager.initialize(getApplicationContext(), R.raw.datafile);
}
}
Warning
The maximum payload size is 3.5 MB. Optimizely rejects requests with a 400 response code,
Bad Request Error
, if the batch payload exceeds this limit.The size limitation is because of the Optimizely Events API, which Full Stack uses to send data to Optimizely.
The most common cause of a large payload size is a high batch size. If your payloads exceed the size limit, try configuring a smaller batch size.
BatchEventProcessor
BatchEventProcessor
BatchEventProcessor
is an implementation of EventProcessor
where events are batched. The class maintains a single consumer thread that pulls events off of the BlockingCollection
and buffers them for either a configured batch size or a maximum duration before the resulting LogEvent
is sent to the EventDispatcher
and NotificationCenter
.
The following properties can be used to customize the BatchEventProcessor
configuration using the Builder class.
Builder methods
Use the following methods to customize the BatchEventProcessor
.
Property | Default value | Description |
---|---|---|
withEventHandler | null | Required field. Specifies event handler to use to dispatch event payload to Optimizely. By default, if you create an Optimizely instance, it passes in AsyncEventHandler to BatchEventProcessor . |
withBatchSize | 10 | The maximum number of events to batch before dispatching. Once this number is reached, all queued events are flushed and sent to Optimizely. |
withFlushInterval | 30000 (30 Seconds) | Maximum time after which to batch and send event payload to Optimizely. In milliseconds. |
withEventQueue | 1000 | BlockingCollection that queues individual events to be batched and dispatched by the executor. |
withNotificationCenter | null | Notification center instance to be used to trigger any notifications to notify when event batches are flushed. |
withExecutor | Single Thread Executor | Executor service that takes care of triggering event batching and subsequent dispatching to Optimizely. |
withTimeout | 5000 | Maximum time to wait for event processor’s close to be executed. In milliseconds. |
Advanced configuration
You can set the following properties can be set to override the default configuration for BatchEventProcessor
.
Property | Default value | Description |
---|---|---|
event.processor.batch.size | 10 | Maximum size of batch of events to send to Optimizely. |
event.processor.batch.interval | 30000 | Maximum time after which to batch and send event payload to Optimizely. In milliseconds. |
event.processor.close.timeout | 5000 | Maximum time to wait for event processor’s close to be executed. In milliseconds. |
For more information, see Initialize Android SDK.
Side effects
The table lists other Optimizely functionality that may be triggered by using this class.
Functionality | Description |
---|---|
LogEvent | Whenever the event processor produces a batch of events, a LogEvent object will be created using the EventFactory .It contains batch of conversion and impression events. This object will be dispatched using the provided event dispatcher and also it will be sent to the notification subscribers |
Notification Listeners | Flush invokes the LOGEVENT notification listener if this listener is subscribed to. |
Register a LogEvent
listener
LogEvent
listenerTo register a LogEvent
notification listener
optimizelyClient.getNotificationCenter().addNotificationHandler(LogEvent.class, logEvent -> {});
LogEvent
LogEvent
LogEvent
object gets created using EventFactory
. It represents the batch of impression and conversion events we send to the Optimizely backend.
Object | Type | Description |
---|---|---|
requestMethod Required (non null) | RequestMethod (Enum) | The HTTP verb to use when dispatching the log event. It can be GET or POST . |
endpointUrl Required (non null) | String | URL to dispatch log event to. |
requestParams Required (non null) | Map<String, String> | Parameters to be set in the log event. |
eventBatch Required | EventBatch | It contains all the information regarding every event which is batched. including list of visitors which contains UserEvent . |
Close Optimizely on application exit
If you enable event batching, it is important that you call the Close method (optimizelyClient.close()
) prior to exiting. This ensures that queued events are flushed as soon as possible to avoid any data loss.
Warning
Because the Optimizely client maintains a buffer of queued events, you must call
close()
on the Optimizely instance before shutting down your application or whenever dereferencing the instance.
Method | Description |
---|---|
close() | Stops all executor threads and flushes the event queue. This method will also stop any scheduledExecutorService that is running for the datafile manager. |
Updated 10 months ago