Разработка YDB SDK
Эта статья - черновик заметок по разработке SDK, может произвольным образом меняться, дополняться и удаляться. Версия НЕ стабильна.
Руководство для разработчиков SDK
Тут описываются общие подходы к построению SDK и реализации клиентов для YDB. Это не прямое указание к действию и не пошаговая инструкция, а скорее описание общих принципов разработки, которых придерхивается команда {{ ydb-short-name }}. Это понимание будет полезно как для исследования кода существующих SDK, так и для разработки собственных.
Общие принципы
- Надёжность - SDK должны быть надёжными в плане сохранности пользовательских данных и должны помогать строить отказоустойчивые системы
- Удобная безопасность - самый удобный способ работы с API должен быть безопасным, в том смысле что там сложно написать код неправильно или ещё хуже сделать ошибку, которая будет незаметно портить работу приложения
GRPC
SDK общается с сервером с по протоколу grpc c protobuf-сообщениями. Серверная версия протоспек есть в репозитории {{ ydb-short-name }}: сервисы/медоды и сообщения.
При этом все наши SDK, за исключением C++
, в качестве источника используют репозиторий https://github.com/ydb-platform/ydb-api-protos. И для новых SDK рекомендуем использовать этот отдельный репозиторий.
Топики
Протокол работы с топиками основан на обмене сообщений с сервеом через двунаправленные стримы + есть отдельные методы, которые вызываются вне этих потоков. Protobuf-сообщения для работы с топиками описаны в файле: https://github.com/ydb-platform/ydb-api-protos/blob/master/protos/ydb_topic.proto
Запись сообщений в топики
Взаимодействие с пользовательским кодом
У SDK есть внутренний буфер, ограничивающий очередь сообщений по количеству и/или размеру в байтах. По-умолчанию клиентский под при вызове SDK записывает сообщения именно в буфер и не ждёт подтверждения от сервера. При этом SDK обязуется доставить сообщения до сервера при отсутствии непоправимых ошибок (ошибки авторизации, завершение процесса и т.п.). Для случаев когда клиентскоиу коду нужно знать о том что сообщение уже точно записано на сервер мы делаем для этого отдельные методы. Базово объект/структура с реализацией записи сообщения у нас называется writer
, метод отправки сообщения на сервер - write
, а метод ожидания пока сообщения запишутся на сервер - flush
.
Разбор протокола
Для записи сообщей устанавливается двусторонний grpc-стрим (вызов TopicService.StreamWrite
). Сообщения, которые отправляются с клиента на сервер расположены внутри StreamWriteMessage.FromClient
, а
Первым идёт сообщение StreamWriteMessage.FromClient.InitRequest
, дальше клиент и сервер обмениваются другими сообщениями. Во время обычной работы сервер отправляет сообщения со статусом StatusIds_SUCCESS
. Любой другой статус означает ошибку и сразу после сообщения с ошибкой сервер закрывает стрим. При получении ошибки SDK проверяет код ошибки и исходя из него либо падает, либо переподключается к серверу и переотправляет сообщения, для которых ещё не получал подтверждений. При этом сервер может закрыть соединение и без ошибки - это нормально и клиенту надо просто переподключиться к серверу.