2016-06-08 5 views
0

Что не так в коде моего go (IO wait)?Что не так в коде go go (IO wait)?

Я проектирую мои промежуточное программное но достиг ошибок (ИО ожидание), когда я запустить команду:

ab -c 100 -n 100000 -k http://127.0.0.1:10000/ 

Полный код выглядит следующим образом: https://github.com/HeadwindFly/examples/blob/master/middleware.go

+2

Рассмотрим размещение соответствующий код здесь. Здесь нам нужно [MCVE] (http://stackoverflow.com/help/mcve). –

+0

@ J.Chomel извините за это, но код слишком длинный, stackoverflow не позволяет публиковать, если вопрос содержит большую часть кода. – HeadwindFly

+1

Код слишком длинный: вот почему я советую вам создать MVCE. Но если у вас его нет, кто-то может занять необходимое время, чтобы помочь вам, кто знает. –

ответ

1

Первое: никаких оснований для использования отражения здесь. Не имеет никакого отношения к вашей проблеме, но она не нужна.

В вашей настройке контекста вы используете глобальный var для ctx.

HTTP-сервер go является параллельным, поэтому то, что вы делаете, состоит в том, что несколько goroutines обновляют один и тот же глобальный var, а затем передают это обработчику.

Это приводит к тому, что ваши обработчики иногда получают один экземпляр ResponseWriter и пытаются записать на него. Это может привести к ошибке ab, так как вы пишете недействительные ответы HTTP, смешивая то, что отправляется на провод.

Избавьтесь от глобальной переменной CTX и использовать локальный один, как показано ниже:

func handler(rw http.ResponseWriter, r *http.Request) { 
    ctx := &Context{ // notice that this is a local var now 
     names:make([]string, 0), 
     rw:rw, 
     r:r, 
    } 

    for i := 0; i < len(middlewareInfos); i++ { 
     middleware := reflect.New(middlewareInfos[i].t) 

     setContextMethod := middleware.MethodByName("SetContext") 
     setContextMethod.Call([]reflect.Value{reflect.ValueOf(ctx)}) 

     handleMethod := middleware.MethodByName("Handle") 
     values := handleMethod.Call([]reflect.Value{}) 

     if value, ok := values[0].Interface().(bool); !ok || !value { 
      return 
     } 
    } 

    // fmt.Printf("%v\n", ctx) 

    fmt.Fprint(rw, "Hello World.") 
} 
Смежные вопросы