Rust Клиенты

Проблема

Высокоуровневые тесты, такие как Bench-TPS, написаны с использованием признака «Клиент». Когда мы выполняем эти тесты как часть набора тестов, мы используем низкоуровневую реализацию BankClient. Когда нам нужно запустить тот же тест для кластера, мы используем реализацию ThinClient. Проблема с этим подходом заключается в том, что это означает, что трейт будет постоянно расширяться, включая новые служебные функции, и все его реализации должны добавлять новые функции. Отделив обращенный к пользователю объект от трейта, который абстрагирует сетевой интерфейс, мы можем расширить обращенный к пользователю объект, включив в него всевозможные полезные функции, такие как «спиннер» из RpcClient, не заботясь о необходимости расширения трейта и его реализации.

Предложенное решение

Вместо того, чтобы реализовывать трейт Client, ThinClient должен быть создан с его реализацией. Таким образом, все служебные функции, которые в настоящее время находятся в трейте Client, могут быть перемещены в ThinClient. «Тонкий клиент» затем может перейти в «solana-sdk», поскольку все его сетевые зависимости будут в реализации «Клиента». Затем мы добавим новую реализацию Client, называемую ClusterClient, и она будет жить в ящике solana-client, где в настоящее время находится ThinClient.

После этой реорганизации любой код, нуждающийся в клиенте, будет написан в терминах «тонкого клиента». В модульных тестах функциональность будет вызываться с помощью ThinClient<BankClient>, тогда как функции main(), эталонные тесты и интеграционные тесты будут вызываться с помощью ThinClient<ClusterClient>.

Если компоненты более высокого уровня требуют большей функциональности, чем та, которую может реализовать BankClient, она должна быть реализована вторым объектом, который реализует второй признак, следуя тому же шаблону, описанному здесь.

Обработка ошибок

Клиент должен использовать существующее перечисление TransportError для ошибок, за исключением того, что поле Custom(String) должно быть изменено на Custom(Box<dyn Error>).

Стратегия реализации

  1. Добавьте новый объект в solana-sdk, RpcClientTng, где суффикс Tng является временным и означает «Следующее поколение».
  2. Инициализируйте RpcClientTng с реализацией SyncClient.
  3. Добавьте в solana-sdk новый объект, ThinClientTng; инициализируйте его с помощью RpcClientTng и реализации AsyncClient
  4. Переместите все модульные тесты из BankClient в ThinClientTng<BankClient>
  5. Добавьте ClusterClient
  6. Переместите пользователей ThinClient в ThinClientTng.
  7. Удалите ThinClient и переименуйте ThinClientTng в ThinClient.
  8. Переместите пользователей RpcClient в новый ThinClient.
  9. Удалите RpcClient и переименуйте RpcClientTng в RpcClient.