Skip to content

Commit

Permalink
wire up sockets
Browse files Browse the repository at this point in the history
  • Loading branch information
nirinchev committed Jun 11, 2024
1 parent 00b3653 commit 4ad12eb
Show file tree
Hide file tree
Showing 21 changed files with 819 additions and 279 deletions.
2 changes: 2 additions & 0 deletions packages/realm_dart/ffigen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ headers:
- 'src/realm_dart_logger.h'
- 'src/realm_dart_decimal128.h'
- 'src/realm_dart_scheduler.h'
- 'src/realm_dart_socket_provider.h'
- 'src/realm_dart_sync.h'
include-directives: # generate only for these headers
- 'src/realm-core/src/realm.h'
- 'src/realm_dart.h'
- 'src/realm_dart_logger.h'
- 'src/realm_dart_decimal128.h'
- 'src/realm_dart_scheduler.h'
- 'src/realm_dart_socket_provider.h'
- 'src/realm_dart_sync.h'
preamble: |
// ignore_for_file: always_specify_types
Expand Down
5 changes: 4 additions & 1 deletion packages/realm_dart/lib/src/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class App {

/// Create an app with a particular [AppConfiguration]. This constructor should only be used on the main isolate and,
/// ideally, only once as soon as the app starts.
App(AppConfiguration configuration) : _handle = AppHandle.from(configuration) {
static Future<App> create(AppConfiguration configuration) async {
// This is not foolproof, but could point people to errors they may have in their app. Realm apps are cached natively, so calling App(config)
// on a background isolate will not recreate the app. Instead, users should construct the app on the main isolate and then call getById on the
// background isolates. This check will log a warning if the isolate name is != 'main' and doesn't start with 'test/' since dart test will
Expand All @@ -107,6 +107,9 @@ class App {
Realm.logger.log(LogLevel.warn,
"App constructor called on Isolate ${Isolate.current.debugName} which doesn't appear to be the main isolate. If you need an app instance on a background isolate use App.getById after constructing the App on the main isolate.");
}

final appHandle = await AppHandle.from(configuration);
return App._(appHandle);
}

/// Obtain an [App] instance by id. The app must have first been created by calling the constructor that takes an [AppConfiguration]
Expand Down
4 changes: 3 additions & 1 deletion packages/realm_dart/lib/src/handles/app_handle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'user_handle.dart';
import 'native/app_handle.dart' if (dart.library.js_interop) 'web/app_handle.dart' as impl;

abstract interface class AppHandle {
factory AppHandle.from(AppConfiguration configuration) = impl.AppHandle.from;
static Future<AppHandle> from(AppConfiguration configuration) => impl.AppHandle.from(configuration);
static AppHandle? get(String id, String? baseUrl) => impl.AppHandle.get(id, baseUrl);

String get id;
Expand All @@ -36,4 +36,6 @@ abstract interface class AppHandle {
Future<void> deleteUser(UserHandle user);
bool resetRealm(String realmPath);
Future<String> callAppFunction(UserHandle user, String functionName, String? argsAsJSON);

void resetForTesting();
}
9 changes: 7 additions & 2 deletions packages/realm_dart/lib/src/handles/native/app_handle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class AppHandle extends HandleBase<realm_app> implements intf.AppHandle {
AppHandle(Pointer<realm_app> pointer) : super(pointer, 16);

static bool _firstTime = true;
factory AppHandle.from(AppConfiguration configuration) {
static Future<AppHandle> from(AppConfiguration configuration) async {
// to avoid caching apps across hot restarts we clear the cache on the first
// time the ctor is called in the root isolate.
if (_firstTime && _isRootIsolate) {
Expand All @@ -40,7 +40,7 @@ class AppHandle extends HandleBase<realm_app> implements intf.AppHandle {
SyncSocketHandle? syncSocketHandle;
if (configuration.useManagedWebsockets) {
final worker = WebsocketHandler();
syncSocketHandle = worker.start();
syncSocketHandle = await worker.start();
}

final appConfigHandle = _createAppConfig(configuration, httpTransportHandle, syncSocketHandle);
Expand Down Expand Up @@ -351,6 +351,11 @@ class AppHandle extends HandleBase<realm_app> implements intf.AppHandle {
return completer.future;
});
}

@override
void resetForTesting() {
realmLib.realm_dart_app_reset_for_testing(pointer).raiseLastErrorIfFalse();
}
}

Pointer<Void> createAsyncFunctionCallbackUserdata(Completer<String> completer) {
Expand Down
86 changes: 86 additions & 0 deletions packages/realm_dart/lib/src/handles/native/realm_bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3411,6 +3411,21 @@ class RealmLibrary {
int,
ffi.Pointer<realm_app_error_t>)>();

bool realm_dart_app_reset_for_testing(
ffi.Pointer<realm_app_t> app,
) {
return _realm_dart_app_reset_for_testing(
app,
);
}

late final _realm_dart_app_reset_for_testingPtr =
_lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<realm_app_t>)>>(
'realm_dart_app_reset_for_testing');
late final _realm_dart_app_reset_for_testing =
_realm_dart_app_reset_for_testingPtr
.asFunction<bool Function(ffi.Pointer<realm_app_t>)>();

void realm_dart_async_open_task_callback(
ffi.Pointer<ffi.Void> userdata,
ffi.Pointer<realm_thread_safe_reference_t> realm,
Expand Down Expand Up @@ -4127,6 +4142,60 @@ class RealmLibrary {
_realm_dart_sync_progress_callbackPtr
.asFunction<void Function(ffi.Pointer<ffi.Void>, int, int, double)>();

ffi.Pointer<realm_sync_socket_t> realm_dart_sync_socket_new(
ffi.Pointer<ffi.Void> userdata,
realm_free_userdata_func_t userdata_free,
ffi.Pointer<realm_scheduler_t> scheduler,
realm_sync_socket_post_func_t post_func,
realm_sync_socket_create_timer_func_t create_timer_func,
realm_sync_socket_timer_canceled_func_t cancel_timer_func,
realm_sync_socket_timer_free_func_t free_timer_func,
realm_sync_socket_connect_func_t websocket_connect_func,
realm_sync_socket_websocket_async_write_func_t websocket_write_func,
realm_sync_socket_websocket_free_func_t websocket_free_func,
) {
return _realm_dart_sync_socket_new(
userdata,
userdata_free,
scheduler,
post_func,
create_timer_func,
cancel_timer_func,
free_timer_func,
websocket_connect_func,
websocket_write_func,
websocket_free_func,
);
}

late final _realm_dart_sync_socket_newPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<realm_sync_socket_t> Function(
ffi.Pointer<ffi.Void>,
realm_free_userdata_func_t,
ffi.Pointer<realm_scheduler_t>,
realm_sync_socket_post_func_t,
realm_sync_socket_create_timer_func_t,
realm_sync_socket_timer_canceled_func_t,
realm_sync_socket_timer_free_func_t,
realm_sync_socket_connect_func_t,
realm_sync_socket_websocket_async_write_func_t,
realm_sync_socket_websocket_free_func_t)>>(
'realm_dart_sync_socket_new');
late final _realm_dart_sync_socket_new =
_realm_dart_sync_socket_newPtr.asFunction<
ffi.Pointer<realm_sync_socket_t> Function(
ffi.Pointer<ffi.Void>,
realm_free_userdata_func_t,
ffi.Pointer<realm_scheduler_t>,
realm_sync_socket_post_func_t,
realm_sync_socket_create_timer_func_t,
realm_sync_socket_timer_canceled_func_t,
realm_sync_socket_timer_free_func_t,
realm_sync_socket_connect_func_t,
realm_sync_socket_websocket_async_write_func_t,
realm_sync_socket_websocket_free_func_t)>();

void realm_dart_sync_wait_for_completion_callback(
ffi.Pointer<ffi.Void> userdata,
ffi.Pointer<realm_error_t> error,
Expand Down Expand Up @@ -11721,6 +11790,9 @@ class _SymbolAddresses {
ffi.Pointer<realm_app_error_t>)>>
get realm_dart_apikey_list_callback =>
_library._realm_dart_apikey_list_callbackPtr;
ffi.Pointer<ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<realm_app_t>)>>
get realm_dart_app_reset_for_testing =>
_library._realm_dart_app_reset_for_testingPtr;
ffi.Pointer<
ffi.NativeFunction<
ffi.Void Function(
Expand Down Expand Up @@ -11901,6 +11973,20 @@ class _SymbolAddresses {
ffi.Pointer<ffi.Void>, ffi.Uint64, ffi.Uint64, ffi.Double)>>
get realm_dart_sync_progress_callback =>
_library._realm_dart_sync_progress_callbackPtr;
ffi.Pointer<
ffi.NativeFunction<
ffi.Pointer<realm_sync_socket_t> Function(
ffi.Pointer<ffi.Void>,
realm_free_userdata_func_t,
ffi.Pointer<realm_scheduler_t>,
realm_sync_socket_post_func_t,
realm_sync_socket_create_timer_func_t,
realm_sync_socket_timer_canceled_func_t,
realm_sync_socket_timer_free_func_t,
realm_sync_socket_connect_func_t,
realm_sync_socket_websocket_async_write_func_t,
realm_sync_socket_websocket_free_func_t)>>
get realm_dart_sync_socket_new => _library._realm_dart_sync_socket_newPtr;
ffi.Pointer<
ffi.NativeFunction<
ffi.Void Function(
Expand Down
Loading

0 comments on commit 4ad12eb

Please sign in to comment.