Как сделать экономный звонок на указанную c службу сервера, который поддерживает несколько версий - PullRequest
0 голосов
/ 05 февраля 2020

Допустим, у меня есть следующие сервисы, объявленные в одном и том же командном файле: [Я опущу определение структуры, поскольку это всего лишь пример]

 service PositionService {
   PositionDTO findPosition(1:positionInputDTO) throws (1:PositionServiceException e);
 }

 service PositionServiceV2 {
   PositionDTO findPosition(1:positionInputDTO) throws (1:PositionServiceException e),
   OwnerStoresListDTO listPositions(1:ListPositionInputDTO) throws (1:PositionServiceException e);
 }

Я скомпилировал этот командный файл и сгенерировал код для сервер в java и go коде для клиента. Затем я попытался вызвать listPositions метод на сервере, используя PositionServiceV2Client, но продолжал получать ошибку Неверное имя метода: listPositions в качестве ответа от сервера.

Имейте в виду, что и клиент, и сервер используют совместимый стек для этих вызовов, я уже реализовал другие сервисы, но это первый из обнаруженных мной сервисов, в котором несколько сервисов объявлены внутри одного и того же командного файла. Как я могу сделать такой звонок? Любая помощь приветствуется.

1 Ответ

0 голосов
/ 06 февраля 2020

Называть новые сервисы «старомодным способом»

Вызов сервера PositionService с использованием клиента PositionServiceV2 невозможен, поскольку это другой сервис. И даже если вы добьетесь успеха, вы все равно столкнетесь с проблемами, когда начнете использовать мультиплексирование услуг.

Даже если имена методов случайно совпадают, как с findPosition(), нет гарантии, что вызов будет успешным. Список аргументов может быть другим, могут быть разные возвращаемые данные или предложение throws может не совпадать. Из договора об интерфейсе это две разные службы.

Итог: Вы можете вызвать службу PositionServiceV2, используя клиент PositionServiceV2, или сервер PositionService, используя PositionService клиент.

Но в этом случае у вас все еще остается возможность. Thrift поддерживает наследование на уровне обслуживания, например:

service PositionService {
    PositionDTO findPosition(1:PositionInputDTO) 
        throws (1: PositionServiceException e);
}

service PositionServiceV2 extends PositionService {
    OwnerStoresListDTO listPositions(1:ListPositionInputDTO)  
        throws (1:PositionServiceException e);
}

Конечно, сервер все еще может отвечать только на вызовы, которые фактически реализованы на стороне сервера. Ориентация на сервер V1 с использованием клиента V2 не будет магически реализовывать интерфейс V2.

Что такое "мягкое управление версиями"?

С Thrift вам не нужно делать все это. Вы можете забыть о том, что мы написали выше, и сделать это еще проще:

service PositionService {

    // this method exists from the beginning
    PositionDTO findPosition(1:PositionInputDTO) 
        throws (1: PositionServiceException e);

    // this method has been added later
    OwnerStoresListDTO listPositions(1:ListPositionInputDTO)  
        throws (1:PositionServiceException e);

    // this method is no longer available
    //void SomeOlderCallThatIsNoLongerSupportedAnymore()
}

Это называется "мягким версионированием", поскольку оно полностью устраняет необходимость различать между собой, вызывать, реализовывать и поддерживать различные "версии" тот же API. Звонок либо есть, либо нет.

Эта концепция была бы невозможна с бинарными API, такими как COM-интерфейсы, потому что изменение существующего API немедленно нарушает контракт. Но это возможно с помощью Thrift и подобных фреймворков. Вы по-прежнему можете вносить несовместимые изменения, если вы достаточно стараетесь, но вы все равно можете вызвать оставшиеся.

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

enum ServerCaps = { CanFoo, CanBar, SupportsBaz }

service PositionService {
    // tell me what features you support
    set<ServerCaps>  GetServerCapabilities()

    //... other methods here ...
}

PS: Спросил и ответил до

...