send method
Send a batch of events. Returns true on success.
Implementation
@override
Future<bool> send(List<TelemetryEvent> events) async {
final payload = jsonEncode({
'events': events.map((e) => e.toJson()).toList(),
'sentAt': DateTime.now().toIso8601String(),
});
for (var attempt = 0; attempt <= maxRetries; attempt++) {
try {
final uri = Uri.parse(endpoint);
final request = await _httpClient
.postUrl(uri)
.timeout(Duration(seconds: timeoutSeconds));
request.headers.set('Content-Type', 'application/json');
if (authToken != null) {
request.headers.set('Authorization', 'Bearer $authToken');
}
request.write(payload);
final response = await request.close().timeout(
Duration(seconds: timeoutSeconds),
);
// Drain the response body so the connection can be reused.
await response.drain<void>();
if (response.statusCode >= 200 && response.statusCode < 300) {
return true;
}
// Retry on server errors only.
if (response.statusCode < 500) return false;
} on TimeoutException {
// Fall through to retry.
} on SocketException {
// Network unreachable — retry.
} catch (e) {
stderr.writeln('[telemetry:http] send error: $e');
return false;
}
// Exponential back-off before retrying.
if (attempt < maxRetries) {
await Future<void>.delayed(
Duration(milliseconds: 200 * (1 << attempt)),
);
}
}
return false;
}