Go http клиент настроен для нескольких конечных точек? - PullRequest
0 голосов
/ 02 марта 2020

Я повторно использую соединение с клиентом http, чтобы совершать внешние звонки на одну конечную точку. Ниже приведен отрывок программы:

var AppCon MyApp

func New(user, pass string, platformURL *url.URL, restContext string) (*MyApp, error) {
  if AppCon == (MyApp{}) {
      AppCon = MyApp{
          user:        user,
          password:    pass,
          URL:         platformURL,
          Client:      &http.Client{Timeout: 30 * time.Second},
          RESTContext: restContext,
      }

      cj, err := cookiejar.New(nil)
      if err != nil {
          return &AppCon, err
      }

      AppCon.cookie = cj
  }

    return &AppCon, nil
}

// This is an example only. There are many more functions which accept *MyApp as a pointer.
func(ma *MyApp) GetUser(name string) (string, error){
   // Return user
}

func main(){   
    for {
      // Get messages from a queue 
      // The message returned from the queue provide info on which methods to call
      // 'm' is a struct with message metadata

      c, err := New(m.un, m.pass, m.url)

      go func(){
        // Do something i.e c.GetUser("123456")
      }()
    }
}

Теперь у меня есть требование настроить клиентские соединения с разными конечными точками / учетными данными, полученными через сообщения очереди.

Проблема, которую я предвидел, заключается в Я не могу просто изменить AppCon новыми деталями конечной точки, так как возвращается указатель на MyApp, что приводит к сбросу c. Это может повлиять на выполнение процедуры HTTP-вызова непреднамеренной конечной точки. Чтобы сделать вещи нетривиальными, программа не предназначена для информирования о конечных точках (я рассматривал использование оператора switch), а скорее получает то, что ей нужно, через сообщения очереди.

Учитывая, что проблемы, которые я назвал, верны, есть ли рекомендации по их решению?

РЕДАКТИРОВАТЬ 1

Основано на При наличии обратной связи я склонен полагать, что это решит мою проблему:

  1. Удалите использование Singleton из MyApp
  2. Отсоедините клиент http от MyApp, что позволит для повторного использования
var httpClient *http.Client

func New(user, pass string, platformURL *url.URL, restContext string) (*MyApp, error) {

    AppCon = MyApp{
          user:        user,
          password:    pass,
          URL:         platformURL,
          Client:      func() *http.Client {
      if httpClient == nil {
        httpClient = &http.Client{Timeout: 30 * time.Second}
      }
        return httpClient
    }()
          RESTContext: restContext,
      }

    return &AppCon, nil
}

// This is an example only. There are many more functions which accept *MyApp as a pointer.
func(ma *MyApp) GetUser(name string) (string, error){
   // Return user
}

func main(){   
    for {
      // Get messages from a queue 
      // The message returned from the queue provide info on which methods to call
      // 'm' is a struct with message metadata

      c, err := New(m.un, m.pass, m.url)

      // Must pass a reference
      go func(c *MyApp){
        // Do something i.e c.GetUser("123456")
      }(c)
    }
}

Я не добавил это как ответ, потому что не хочу предполагать, что это на 100% правильно, так как я все еще учусь, и у меня могут быть другие заблуждения правильный.

1 Ответ

0 голосов
/ 02 марта 2020

Отказ от ответственности: это не прямой ответ на ваш вопрос, а скорее попытка направить вас к правильному способу решения вашей проблемы.

  • Старайтесь избегать единственного шаблона для вас MyApp , Кроме того, New вводит в заблуждение, фактически он не создает новый объект каждый раз. Вместо этого вы могли бы каждый раз создавать новый экземпляр, сохраняя соединение клиента http.
  • Не используйте конструкции, подобные этой: AppCon == (MyApp{}), однажды вы будете стрелять в ногу, делая это. Вместо этого используйте указатель и сравните его с nil.
  • Избегайте условий гонки. В вашем коде вы запускаете программу и сразу переходите к новой итерации for l oop. Учитывая, что вы повторно используете весь экземпляр MyApp, вы, по сути, вводите условие гонки.
  • Используя файлы cookie, вы делаете свое соединение с сохранением состояния, но ваша задача требует подключения без сохранения состояния. В таком подходе может быть что-то не так.
...