Skip to content

Commit c7d6ad1

Browse files
committed
Readme - Service[Params]SafeProvider
1 parent 753b6c9 commit c7d6ad1

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

README.md

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ You can create `ServiceProvider` in several ways:
368368
You can create `ServiceParamsProvider` by using a factory with parameters (`ServiceParamsFactory`): `ServiceParamsProvider(factory:)` or using closure `ServiceParamsProvider { params in }`.
369369

370370
To get the service it is enough to call the function `try Service[Params]Provider.getService()` which returns the service or error.
371-
You can also use `Service[Params]Provider.getServiceAsOptional()` - then the service is returned as an option (nil in case of an error) or `Service[Params]Provider.getServiceOrFatal()` - in case of an error, there will be a crash with detailed information about the error.
371+
You can also use `Service[Params]Provider.getServiceAsResult()`, `Service[Params]Provider.getServiceAsOptional()` - then the service is returned as an option (nil in case of an error) or `Service[Params]Provider.getServiceOrFatal()` - in case of an error, there will be a crash with detailed information about the error.
372372
Use `getServiceOrFatal()` instead of `try! getService()` or `getServiceAsOptional()!`, so that the cause of the crash is not lost and is easily determined.
373373

374374
#
@@ -384,7 +384,7 @@ Use `getServiceOrFatal()` instead of `try! getService()` or `getServiceAsOption
384384
Создать `ServiceParamsProvider` можно используя фабрику с параметрами (`ServiceParamsFactory`) `ServiceParamsProvider(factory:)` или используя кложур `ServiceParamsProvider { params in }`.
385385

386386
Для получения сервиса достаточно вызвать функцию `try Service[Params]Provider.getService()` которая возвращает сервис или ошибку.
387-
Также можно использовать `Service[Params]Provider.getServiceAsOptional()` - тогда сервис возвращается как опционал (nil в случае ошибки) или `Service[Params]Provider.getServiceOrFatal()` - в случае ошибки будет краш с подробной информацией об ошибке.
387+
Также можно использовать `Service[Params]Provider.getServiceAsResult()`, `Service[Params]Provider.getServiceAsOptional()` - тогда сервис возвращается как опционал (nil в случае ошибки) или `Service[Params]Provider.getServiceOrFatal()` - в случае ошибки будет краш с подробной информацией об ошибке.
388388
Используйте `getServiceOrFatal()` вместо `try! getService()` или `getServiceAsOptional()!`, чтобы причина краша не потерялась и была легко определима.
389389

390390

@@ -402,6 +402,46 @@ do {
402402
}
403403
```
404404

405+
### Service[Params]SafeProvider
406+
407+
In some cases, you may need to get services from different threads. To support multithreading, you can use special thread-safe providers. Their task is to make each service receipt thread-safe by blocking or using synchronously a separate queue for each access to the provider and the factory.
408+
This is usually not required, because the configuration of services at the start of the application and their receipt in the presentation layer occurs in the main thread. But if there are cases when the service is requested not from the main thread - you should use a secure provider. Getting the service from such a provider may be slower than usual.
409+
410+
To create a secure provider, use the `serviceSafeProvider()` or constructor methods.
411+
The default is `NSLock`, but you can choose `DispatchSemaphore` or a separate queue `DispatchQueue`.
412+
413+
`Service[Params]SafeProvider` is a inheritance of regular providers, so the entire standard set of methods is available and you can store and pass such a provider as a regular one. But in addition, there is one method - `getServiceAsResultNotSafe()`, which will ignore any locks and perform the usual non-secure getting of the service.
414+
415+
#
416+
417+
В некоторых случаях может потребоваться получать сервисы из разных потоков. Чтобы поддержать мультипоточность можно использовать специальные потоко-безопасные провайдеры. Их задача - каждое получение сервиса сделать потоко-безопасным, блокируя или используя синхронно отдельную очередь при каждом обращении к првайдеру и фабрике.
418+
Обычно это не требуется, т.к. настройка сервисов при старте приложения и их получения в слое презентации происходит в главном потоке. Но если есть случаи когда сервис запрашивается не из главного потока - следует использовать безопасный провайдер. Получение сервиса у такого провайдера может быть медленнее обычного.
419+
420+
Для создания безпасного провайдера используются методы `serviceSafeProvider()` или конструктор.
421+
По умолчанию используется `NSLock`, но вы можете выбрать `DispatchSemaphore` или отдельную очередь `DispatchQueue`.
422+
423+
`Service[Params]SafeProvider` является наследником обычных провайдеров, поэтому доступен весь стандартный набор методов и можно хранить и передавать такой провайдер как обычный. Но в дополнение есть один метод - `getServiceAsResultNotSafe()`, который проигнорирует любые блокировки и выполнит обычное не безопасное получение сервиса.
424+
425+
426+
```swift
427+
struct ServiceContainer {
428+
let firstService: ServiceProvider<FirstService>
429+
}
430+
431+
extension ServiceContainer {
432+
static func makeDefault() -> ServiceContainer {
433+
let firstService: ServiceSafeProvider<FirstService> = FirstServiceFactory().serviceSafeProvider(safeThread: .lock)
434+
435+
return .init(
436+
firstService: firstService
437+
)
438+
}
439+
}
440+
441+
let service = container.firstService.getServiceAsOptional()
442+
```
443+
444+
405445
### Support Objective-C
406446

407447
Creating and configuring the container is only available for swift code, but for objective-c, you can provide a special wrapper to getting the services.

0 commit comments

Comments
 (0)