2011-07-14 6 views
1

httpサーバをリモートで停止したいのですが、停止した後に停止したことを示すメッセージが表示されます。それは私にいくつかの問題を引き起こしています。私が見つけることができる唯一の解決策は、私が理想とは考えていない以下のようなものです。 誰かがより良い解決策を提供することができます。問題は、「go func(){」のようにゴルーチンを使用しない限り、クライアントに送信される最終メッセージが通過しないことです。次のようにリモートでhttpサーバを停止したい

コードは次のとおりです。


//************* 
func stopServer(ohtWriter http.ResponseWriter, phtRequest *http.Request) {// Stop The Server 
//************* 

    var iBytesSent int 
    var oOsError os.Error 
    var sErmes string 

    println("Stopping Server") 

    iBytesSent,oOsError = ohtWriter.Write([]byte("Message from server - server now stopped.")) 

    if oOsError != nil { 
     sErmes = ". Error = " +oOsError.String() 
    } else { 
     sErmes = ". No error on write" 
    } 

    println("stopServer: Bytes sent = " +strconv.Itoa(iBytesSent) +sErmes) 

    ohtFlusher, tCanFlush := ohtWriter.(http.Flusher) 
    if tCanFlush { 
     ohtFlusher.Flush() 
    } 

    go func() { 
     time.Sleep(3e9) 
     os.Exit(0) 
    }() 
} 

答えて

2

ええ、httpパッケージのサポートがなければ、正常なシャットダウンは実際には不可能だと思います。これはおそらく少し劣っているかもしれませんが、このリクエストの時点で他の同時リクエストはまだ閉鎖されています。おそらくGo issue trackerで機能要求を提出してみてください。もっと良い方法は、httpパッケージを開き、正常なシャットダウン方法を追加することです。submit it

編集:私はアプリ内http.Handlersのすべてをコントロールしている場合、あなたは(適切なスレッド同期を使用して)飛行中の要求の数を維持し、に以下のコードを修正することができると思います)新しい拒否「シャットダウン」一度接続が呼ばれると、b)

package main 

import (
    "http" 
    "os" 
    "io" 
    "log" 
    "strconv" 
) 

func main() { 
    http.HandleFunc("/", ServeHTTP) 
    http.ListenAndServe(":8081", nil) 
} 

const responseString = "Shutting down\n" 

func ServeHTTP(w http.ResponseWriter, req *http.Request) { 
    w.Header().Set("Content-Type", "text/plain; charset=utf-8") 
    w.Header().Set("Content-Length", strconv.Itoa(len(responseString))) 
    io.WriteString(w, responseString) 

    f, canFlush := w.(http.Flusher) 
    if canFlush { 
     f.Flush() 
    } 

    conn, _, err := w.(http.Hijacker).Hijack() 
    if err != nil { 
     log.Fatalf("error while shutting down: %v", err) 
    } 

    conn.Close() 

    log.Println("Shutting down") 
    os.Exit(0) 
} 
+0

に感謝します。私はhttpパッケージに何かが必要であることに同意しますが、今は私を少し超えています。 – brianoh

0

はまだ試していませんが、直接http.ServerConnを使用するとうまくいくかもしれません。

+0

私はhttp.ServerConnを見つけることができなかった、これは最近のバージョンで削除されましたか? – CyberFonic

+0

@Cyber​​Fonicいいえ、それは 'httputil'パッケージ(ここでは(http://golang.org/doc/go1.html#http)を参照) –

0

ここで地域の発展のために十分に良いことだ簡単な方法だ...シャットダウンする前に完了するために、すべてのインフライトリクエストを待つれます。

http://www.sergiotapia.me/how-to-stop-your-go-http-server/


package main 

import ( 
    "net/http" 
    "os" 

    "github.com/bmizerany/pat" 
) 

var mux = pat.New() 

func main() { 
    mux.Get("/kill", http.HandlerFunc(kill)) 
    http.Handle("/", mux) 
    http.ListenAndServe(":8080", nil) 
} 

func kill(w http.ResponseWriter, r *http.Request) { 
    os.Exit(0) 
} 
関連する問題