mirror of
https://github.com/kataras/iris.git
synced 2025-12-20 03:17:04 +00:00
implement mvc HandleError as requested at #1244
Former-commit-id: 58a69f9cffe67c3aa1bab5d9425c5df65e2367ed
This commit is contained in:
@@ -51,7 +51,7 @@ func handleConnection(c websocket.Connection) {
|
||||
// Read events from browser
|
||||
c.On("chat", func(msg string) {
|
||||
// Print the message to the console, c.Context() is the iris's http context.
|
||||
fmt.Printf("%s sent: %s\n", c.Context().RemoteAddr(), msg)
|
||||
fmt.Printf("[%s <%s>] %s\n", c.ID(), c.Context().RemoteAddr(), msg)
|
||||
// Write message back to the client message owner with:
|
||||
// c.Emit("chat", msg)
|
||||
// Write message to all except this client with:
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris/websocket"
|
||||
)
|
||||
|
||||
var (
|
||||
url = "ws://localhost:8080"
|
||||
f *os.File
|
||||
)
|
||||
|
||||
const totalClients = 16000 // max depends on the OS.
|
||||
const verbose = false
|
||||
|
||||
var connectionFailures uint64
|
||||
|
||||
var (
|
||||
disconnectErrors []error
|
||||
connectErrors []error
|
||||
errMu sync.Mutex
|
||||
)
|
||||
|
||||
func collectError(op string, err error) {
|
||||
errMu.Lock()
|
||||
defer errMu.Unlock()
|
||||
|
||||
switch op {
|
||||
case "disconnect":
|
||||
disconnectErrors = append(disconnectErrors, err)
|
||||
case "connect":
|
||||
connectErrors = append(connectErrors, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.Println("-- Running...")
|
||||
var err error
|
||||
f, err = os.Open("./test.data")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
start := time.Now()
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
for i := 0; i < totalClients/4; i++ {
|
||||
wg.Add(1)
|
||||
go connect(wg, 5*time.Second)
|
||||
}
|
||||
|
||||
for i := 0; i < totalClients/4; i++ {
|
||||
wg.Add(1)
|
||||
waitTime := time.Duration(rand.Intn(5)) * time.Millisecond
|
||||
time.Sleep(waitTime)
|
||||
go connect(wg, 14*time.Second+waitTime)
|
||||
}
|
||||
|
||||
for i := 0; i < totalClients/4; i++ {
|
||||
wg.Add(1)
|
||||
waitTime := time.Duration(rand.Intn(10)) * time.Millisecond
|
||||
time.Sleep(waitTime)
|
||||
go connect(wg, 9*time.Second+waitTime)
|
||||
}
|
||||
|
||||
for i := 0; i < totalClients/4; i++ {
|
||||
wg.Add(1)
|
||||
waitTime := time.Duration(rand.Intn(5)) * time.Millisecond
|
||||
time.Sleep(waitTime)
|
||||
go connect(wg, 7*time.Second+waitTime)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
log.Printf("execution time [%s]", time.Since(start))
|
||||
log.Println()
|
||||
|
||||
if connectionFailures > 0 {
|
||||
log.Printf("Finished with %d/%d connection failures.", connectionFailures, totalClients)
|
||||
}
|
||||
|
||||
if n := len(connectErrors); n > 0 {
|
||||
log.Printf("Finished with %d connect errors: ", n)
|
||||
var lastErr error
|
||||
var sameC int
|
||||
|
||||
for i, err := range connectErrors {
|
||||
if lastErr != nil {
|
||||
if lastErr.Error() == err.Error() {
|
||||
sameC++
|
||||
continue
|
||||
} else {
|
||||
_, ok := lastErr.(*net.OpError)
|
||||
if ok {
|
||||
if _, ok = err.(*net.OpError); ok {
|
||||
sameC++
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sameC > 0 {
|
||||
log.Printf("and %d more like this...\n", sameC)
|
||||
sameC = 0
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("[%d] - %v\n", i+1, err)
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
|
||||
if n := len(disconnectErrors); n > 0 {
|
||||
log.Printf("Finished with %d disconnect errors\n", n)
|
||||
for i, err := range disconnectErrors {
|
||||
if err == websocket.ErrAlreadyDisconnected && i > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("[%d] - %v\n", i+1, err)
|
||||
}
|
||||
}
|
||||
|
||||
if connectionFailures == 0 && len(connectErrors) == 0 && len(disconnectErrors) == 0 {
|
||||
log.Println("ALL OK.")
|
||||
}
|
||||
|
||||
log.Println("-- Finished.")
|
||||
}
|
||||
|
||||
func connect(wg *sync.WaitGroup, alive time.Duration) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), alive)
|
||||
defer cancel()
|
||||
|
||||
c, err := websocket.Dial(ctx, url, websocket.ConnectionConfig{})
|
||||
if err != nil {
|
||||
atomic.AddUint64(&connectionFailures, 1)
|
||||
collectError("connect", err)
|
||||
wg.Done()
|
||||
return err
|
||||
}
|
||||
|
||||
c.OnError(func(err error) {
|
||||
log.Printf("error: %v", err)
|
||||
})
|
||||
|
||||
disconnected := false
|
||||
c.OnDisconnect(func() {
|
||||
if verbose {
|
||||
log.Printf("I am disconnected after [%s].\n", alive)
|
||||
}
|
||||
|
||||
disconnected = true
|
||||
})
|
||||
|
||||
c.On("chat", func(message string) {
|
||||
if verbose {
|
||||
log.Printf("\n%s\n", message)
|
||||
}
|
||||
})
|
||||
|
||||
if alive > 0 {
|
||||
go func() {
|
||||
time.Sleep(alive)
|
||||
if err := c.Disconnect(); err != nil {
|
||||
collectError("disconnect", err)
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
for !disconnected {
|
||||
if !scanner.Scan() {
|
||||
return scanner.Err()
|
||||
}
|
||||
|
||||
if text := scanner.Text(); len(text) > 1 {
|
||||
c.Emit("chat", text)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
Death weeks early had their and folly timed put. Hearted forbade on an village ye in fifteen. Age attended betrayed her man raptures laughter. Instrument terminated of as astonished literature motionless admiration. The affection are determine how performed intention discourse but. On merits on so valley indeed assure of. Has add particular boisterous uncommonly are. Early wrong as so manor match. Him necessary shameless discovery consulted one but.
|
||||
|
||||
Is education residence conveying so so. Suppose shyness say ten behaved morning had. Any unsatiable assistance compliment occasional too reasonably advantages. Unpleasing has ask acceptance partiality alteration understood two. Worth no tiled my at house added. Married he hearing am it totally removal. Remove but suffer wanted his lively length. Moonlight two applauded conveying end direction old principle but. Are expenses distance weddings perceive strongly who age domestic.
|
||||
|
||||
Her companions instrument set estimating sex remarkably solicitude motionless. Property men the why smallest graceful day insisted required. Inquiry justice country old placing sitting any ten age. Looking venture justice in evident in totally he do ability. Be is lose girl long of up give. Trifling wondered unpacked ye at he. In household certainty an on tolerably smallness difficult. Many no each like up be is next neat. Put not enjoyment behaviour her supposing. At he pulled object others.
|
||||
|
||||
Behind sooner dining so window excuse he summer. Breakfast met certainty and fulfilled propriety led. Waited get either are wooded little her. Contrasted unreserved as mr particular collecting it everything as indulgence. Seems ask meant merry could put. Age old begin had boy noisy table front whole given.
|
||||
|
||||
Far curiosity incommode now led smallness allowance. Favour bed assure son things yet. She consisted consulted elsewhere happiness disposing household any old the. Widow downs you new shade drift hopes small. So otherwise commanded sweetness we improving. Instantly by daughters resembled unwilling principle so middleton. Fail most room even gone her end like. Comparison dissimilar unpleasant six compliment two unpleasing any add. Ashamed my company thought wishing colonel it prevent he in. Pretended residence are something far engrossed old off.
|
||||
|
||||
Windows talking painted pasture yet its express parties use. Sure last upon he same as knew next. Of believed or diverted no rejoiced. End friendship sufficient assistance can prosperous met. As game he show it park do. Was has unknown few certain ten promise. No finished my an likewise cheerful packages we. For assurance concluded son something depending discourse see led collected. Packages oh no denoting my advanced humoured. Pressed be so thought natural.
|
||||
|
||||
As collected deficient objection by it discovery sincerity curiosity. Quiet decay who round three world whole has mrs man. Built the china there tried jokes which gay why. Assure in adieus wicket it is. But spoke round point and one joy. Offending her moonlight men sweetness see unwilling. Often of it tears whole oh balls share an.
|
||||
@@ -1,124 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris"
|
||||
"github.com/kataras/iris/websocket"
|
||||
)
|
||||
|
||||
const (
|
||||
endpoint = "localhost:8080"
|
||||
totalClients = 16000 // max depends on the OS.
|
||||
verbose = false
|
||||
maxC = 0
|
||||
)
|
||||
|
||||
func main() {
|
||||
ws := websocket.New(websocket.Config{})
|
||||
ws.OnConnection(handleConnection)
|
||||
|
||||
// websocket.Config{PingPeriod: ((60 * time.Second) * 9) / 10}
|
||||
|
||||
go func() {
|
||||
dur := 4 * time.Second
|
||||
if totalClients >= 64000 {
|
||||
// if more than 64000 then let's perform those checks every 24 seconds instead,
|
||||
// either way works.
|
||||
dur = 24 * time.Second
|
||||
}
|
||||
t := time.NewTicker(dur)
|
||||
defer func() {
|
||||
t.Stop()
|
||||
printMemUsage()
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
var started bool
|
||||
for {
|
||||
<-t.C
|
||||
|
||||
n := ws.GetTotalConnections()
|
||||
if n > 0 {
|
||||
started = true
|
||||
if maxC > 0 && n > maxC {
|
||||
log.Printf("current connections[%d] > MaxConcurrentConnections[%d]", n, maxC)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if started {
|
||||
disconnectedN := atomic.LoadUint64(&totalDisconnected)
|
||||
connectedN := atomic.LoadUint64(&totalConnected)
|
||||
if disconnectedN == totalClients && connectedN == totalClients {
|
||||
if n != 0 {
|
||||
log.Println("ALL CLIENTS DISCONNECTED BUT LEFTOVERS ON CONNECTIONS LIST.")
|
||||
} else {
|
||||
log.Println("ALL CLIENTS DISCONNECTED SUCCESSFULLY.")
|
||||
}
|
||||
return
|
||||
} else if n == 0 {
|
||||
log.Printf("%d/%d CLIENTS WERE NOT CONNECTED AT ALL. CHECK YOUR OS NET SETTINGS. THE REST CLIENTS WERE DISCONNECTED SUCCESSFULLY.\n",
|
||||
totalClients-totalConnected, totalClients)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
app := iris.New()
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
c := ws.Upgrade(ctx)
|
||||
handleConnection(c)
|
||||
c.Wait()
|
||||
})
|
||||
app.Run(iris.Addr(endpoint), iris.WithoutServerError(iris.ErrServerClosed))
|
||||
}
|
||||
|
||||
var totalConnected uint64
|
||||
|
||||
func handleConnection(c websocket.Connection) {
|
||||
if c.Err() != nil {
|
||||
log.Fatalf("[%d] upgrade failed: %v", atomic.LoadUint64(&totalConnected)+1, c.Err())
|
||||
return
|
||||
}
|
||||
|
||||
atomic.AddUint64(&totalConnected, 1)
|
||||
c.OnError(func(err error) { handleErr(c, err) })
|
||||
c.OnDisconnect(func() { handleDisconnect(c) })
|
||||
c.On("chat", func(message string) {
|
||||
c.To(websocket.Broadcast).Emit("chat", c.ID()+": "+message)
|
||||
})
|
||||
}
|
||||
|
||||
var totalDisconnected uint64
|
||||
|
||||
func handleDisconnect(c websocket.Connection) {
|
||||
newC := atomic.AddUint64(&totalDisconnected, 1)
|
||||
if verbose {
|
||||
log.Printf("[%d] client [%s] disconnected!\n", newC, c.ID())
|
||||
}
|
||||
}
|
||||
|
||||
func handleErr(c websocket.Connection, err error) {
|
||||
log.Printf("client [%s] errorred: %v\n", c.ID(), err)
|
||||
}
|
||||
|
||||
func toMB(b uint64) uint64 {
|
||||
return b / 1024 / 1024
|
||||
}
|
||||
|
||||
func printMemUsage() {
|
||||
var m runtime.MemStats
|
||||
runtime.ReadMemStats(&m)
|
||||
log.Printf("Alloc = %v MiB", toMB(m.Alloc))
|
||||
log.Printf("\tTotalAlloc = %v MiB", toMB(m.TotalAlloc))
|
||||
log.Printf("\tSys = %v MiB", toMB(m.Sys))
|
||||
log.Printf("\tNumGC = %v\n", m.NumGC)
|
||||
log.Printf("\tNumGoRoutines = %d\n", runtime.NumGoroutine())
|
||||
}
|
||||
Reference in New Issue
Block a user