Многопоточность серверного клиента FB2.5

Привет всем.

В FB2.5 реализация API стала защищенной в плане многопоточного использования в рамках одного подключения. Дословно:

The client libraries, including the embedded one, can now be used in multi-threaded applications without any application-level synchronization.

Тут возникает два риторических вопроса.

1. А это тестировалось?
Я имею в виду — «по-настоящему». Исходя из опыта работы с самим сервером (в процессе тестирования 2.5) — там с MT выплыло очень многое. К примеру, InMemory B+ дерево, которое меняло свое состояние при чтении и два читателя убивали сервер. Пользуясь случаем хочется передать привет Коле Самофатову.

Впрочем, с сервером в плане тестирования все понятно — у разработчиков есть (ведь правда — есть?) стрессовая система. Да и у нас тоже неплохая многопоточная страшилка для сервера. Этой страшилкой новейший IB2010 был завален без особых усилий. С FB2.5 на стареньком Q6600 — приходится реально попотеть. С FB2.5.1 наверное прийдется потеть кровью.

А вот с клиентом — непонятно. IBProvider самостоятельно выполняет всю необходимую синхронизацию, поэтому через него клиента особо то не потестишь. Ну, только если работу с разными подключениями. Что, фактически, и делается.

2. Ну и что?
Есть старые клиенты, где этой синхронизации нет.

Серверное API является «процедурно»-ориентированным. Все ресурсы представлены в виде дескрипторов. Новый fbclient.dll защищает именно дескрипторы. Но он защищает где? Внутри себя. А работа с ними (дескрипторами) состоит из двух этапов. Один — на верхнем уровне (скажем в компонентах доступа). А второй уровень — как раз в fbclient.dll. Любой, знакомый с принципами MT-синхронизации, понимает — защита должна распространяться на оба уровня. Чтобы не было так:

1. Поток 1. [USER] Транзакция_handle1 активна? Нет не, активна.
2. Поток 2. [USER] Транзакция_handle1 активна? Нет не, активна.
3. Поток 1. [ENTER in FBCLIENT] [MT-SAFE] Запуск транзакции_handle1
4. Поток 2. [ENTER in FBCLIENT] [MT-SAFE] Запуск транзакции_handle1
5. Поток 1. Все нормально.
6. Поток 2. Ошибка — транзакция_handle1 уже активна.

Навеяло

А зачем isc_start_transaction проверяет переданный (*tr_handle) на NULL?

Да вот как раз для этого и проверяет, чтобы не убить данные о другой транзакции, обслуживаемой этим дескриптором. Надо бы, конечно посмотреть — где именно он проверяем. До или после блокировки дескриптора. Но лень.

Навеяло2

По-злобному,
5.1 Поток1 [USER] Закрываем дескриптор транзации.
5.2 Поток1 [USER] Освобождаем память, в которой этой дескриптор хранился.

Так что… Пока API не станет

A. Самодостаточным. То есть, оно станет настолько совершенным, что ему высокоуровневые компоненты (второй слой) даром не нужны будут.
Б. Объектно-ориентированным. Это исключает появление болтающихся (на пользовательском уровне) дескрипторов.

обольщаться насчет 2.5 — не стоит. Синхронизация на уровне ваших любимых компонент доступа, работающих через ISC API, нужна. Правда, для полноценной MT-работы, одной только этой блокировки все равно не достаточно.

У FB.NET есть шанс удовлетворять обоим пунктам. Хотя, насколько я в курсе, его автор еще не дорос до мысли добавить MT-сихронизацию. По крайней мере, на его форуме мелькали сообщения о MT-проблемах. Да и у меня сомнения насчет совершенности интефейсов ADO.NET как таковых.

У Java-клиента — тоже. А может у него уже «все в шоколаде». Не в курсе абсолютно.

Немного позитива
Сейчас описание ошибок обращения к API стало хранится в TLS, а не в сетевом пакете. Это гуд, однозначно. Особенно для тех, кто в курсе, что конкретно это дает.

Хотя в IBProvider мы на это закладываться, скорее всего, не будем. Нет смысла … Хмм … По-моему, все таки заложились. В обработчике ошибок отмены текущей операции на сервере… Посмотрел. Ага, точно — заложились…. А может это мы заложились, а работает оно совсем по-другому …

Напоследок.
Строго между нами, девочками. IBProvider не только позволяет пользователю работать с одним подключением из разных потоков. Да он и сам это делает — в сервисном потоке пула запросов. Когда запускаешь тесты на VBS, которые заюзывают пул подключений, созерцание страницы потоков в ProcessExplorer-e просто завораживает. Главное, не пытаться думать «а что и как там конкретно сейчас работает» — может сорвать башню 🙂

Leave a Comment