From 55e4cf038e315a793984a323ba800a5f56f8877d Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Tue, 7 Aug 2018 12:43:51 +0300 Subject: [PATCH] add example for hero *sessions.Session dependency which is used on an index route outside of the main package, it is as easy as it shown. Added mostly after the issue: https://github.com/kataras/iris/issues/1057 -- have fun Former-commit-id: 93338d0e03d6be885edf783c09a2c181568e9ec5 --- _examples/hero/sessions/main.go | 40 +++++++ _examples/hero/sessions/routes/index.go | 26 +++++ .../tutorial/api-for-apache-kafka/src/main.go | 6 ++ core/router/api_builder_benchmark_test.go | 101 ++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 _examples/hero/sessions/main.go create mode 100644 _examples/hero/sessions/routes/index.go create mode 100644 core/router/api_builder_benchmark_test.go diff --git a/_examples/hero/sessions/main.go b/_examples/hero/sessions/main.go new file mode 100644 index 00000000..aa1f67b3 --- /dev/null +++ b/_examples/hero/sessions/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "time" + + "github.com/kataras/iris/_examples/hero/sessions/routes" + + "github.com/kataras/iris" + "github.com/kataras/iris/hero" // <- IMPORTANT + "github.com/kataras/iris/sessions" +) + +func main() { + app := iris.New() + sessionManager := sessions.New(sessions.Config{ + Cookie: "site_session_id", + Expires: 60 * time.Minute, + AllowReclaim: true, + }) + + // Register + // dynamic dependencies like the *sessions.Session, from `sessionManager.Start(ctx) *sessions.Session` <- it accepts a Context and it returns + // something -> this is called dynamic request-time dependency and that "something" can be used to your handlers as input parameters, + // no limit about the number of dependencies, each handler will be builded once, before the server ran and it will use only dependencies that it needs. + hero.Register(sessionManager.Start) + // convert any function to an iris Handler, their input parameters are being resolved using the unique Iris' blazing-fast dependency injection + // for services or dynamic dependencies like the *sessions.Session, from sessionManager.Start(ctx) *sessions.Session) <- it accepts a context and it returns + // something-> this is called dynamic request-time dependency. + indexHandler := hero.Handler(routes.Index) + + // Method: GET + // Path: http://localhost:8080 + app.Get("/", indexHandler) + + app.Run( + iris.Addr(":8080"), + iris.WithoutVersionChecker, + iris.WithoutServerError(iris.ErrServerClosed), + ) +} diff --git a/_examples/hero/sessions/routes/index.go b/_examples/hero/sessions/routes/index.go new file mode 100644 index 00000000..d5b12870 --- /dev/null +++ b/_examples/hero/sessions/routes/index.go @@ -0,0 +1,26 @@ +package routes + +import ( + "github.com/kataras/iris" + "github.com/kataras/iris/sessions" +) + +// Index will increment a simple int version based on the visits that this user/session did. +func Index(ctx iris.Context, session *sessions.Session) { + // it increments a "visits" value of integer by one, + // if the entry with key 'visits' doesn't exist it will create it for you. + visits := session.Increment("visits", 1) + + // write the current, updated visits. + ctx.Writef("%d visit(s) from my current session", visits) +} + +/* +You can also do anything that an MVC function can, i.e: + +func Index(ctx iris.Context,session *sessions.Session) string { + visits := session.Increment("visits", 1) + return fmt.Spritnf("%d visit(s) from my current session", visits) +} +// you can also omit iris.Context input parameter and use dependency injection for LoginForm and etc. <- look the mvc examples. +*/ diff --git a/_examples/tutorial/api-for-apache-kafka/src/main.go b/_examples/tutorial/api-for-apache-kafka/src/main.go index 9b7b5d05..8c20df0c 100644 --- a/_examples/tutorial/api-for-apache-kafka/src/main.go +++ b/_examples/tutorial/api-for-apache-kafka/src/main.go @@ -46,6 +46,12 @@ func init() { config.Producer.Retry.Max = 10 // Retry up to 10 times to produce the message. config.Producer.Return.Successes = true + // for SASL/basic plain text authentication: config.Net.SASL. + // config.Net.SASL.Enable = true + // config.Net.SASL.Handshake = false + // config.Net.SASL.User = "myuser" + // config.Net.SASL.Password = "mypass" + config.Consumer.Return.Errors = true } diff --git a/core/router/api_builder_benchmark_test.go b/core/router/api_builder_benchmark_test.go new file mode 100644 index 00000000..04c1fd0e --- /dev/null +++ b/core/router/api_builder_benchmark_test.go @@ -0,0 +1,101 @@ +package router + +import ( + "math/rand" + "strings" + "testing" + "time" + + "github.com/kataras/iris/context" +) + +// +// randStringBytesMaskImprSrc helps us to generate random paths for the test, +// the below piece of code is external, as an answer to a stackoverflow question. +// +// START. +const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +const ( + letterIdxBits = 6 // 6 bits to represent a letter index + letterIdxMask = 1<= 0; { + if remain == 0 { + cache, remain = src.Int63(), letterIdxMax + } + if idx := int(cache & letterIdxMask); idx < len(letterBytes) { + b[i] = letterBytes[idx] + i-- + } + cache >>= letterIdxBits + remain-- + } + + return strings.ToLower(string(b)) +} + +// END. + +func genPaths(routesLength, minCharLength, maxCharLength int) []string { + b := new(strings.Builder) + paths := make([]string, routesLength) + pathStart := '/' + for i := 0; i < routesLength; i++ { + pathSegmentCharsLength := rand.Intn(maxCharLength-minCharLength) + minCharLength + + b.WriteRune(pathStart) + b.WriteString(randStringBytesMaskImprSrc(pathSegmentCharsLength)) + b.WriteString("/{name:string}/") // sugar. + b.WriteString(randStringBytesMaskImprSrc(pathSegmentCharsLength)) + b.WriteString("/{age:int}/end") + paths[i] = b.String() + + b.Reset() + } + + return paths +} + +// Build 1296(=144*9(the available http methods)) routes +// with up to 2*range(15-42)+ 2 named paths lowercase letters +// and 12 request handlers each. +// +// GOCACHE=off && go test -run=XXX -bench=BenchmarkAPIBuilder$ -benchtime=10s +func BenchmarkAPIBuilder(b *testing.B) { + rand.Seed(time.Now().Unix()) + + noOpHandler := func(ctx context.Context) {} + handlersPerRoute := make(context.Handlers, 12) + for i := 0; i < cap(handlersPerRoute); i++ { + handlersPerRoute[i] = noOpHandler + } + + routesLength := 144 + // i.e /gzhyweumidvelqewrvoyqmzopvuxli/{name:string}/bibrkratnrrhvsjwsxygfwmqwhcstc/{age:int}/end + paths := genPaths(routesLength, 15, 42) + + api := NewAPIBuilder() + requestHandler := NewDefaultHandler() + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < routesLength; i++ { + api.Any(paths[i], handlersPerRoute...) + } + + if err := requestHandler.Build(api); err != nil { + b.Fatal(err) + } + + b.StopTimer() + + b.Logf("%d routes have just builded\n", len(api.GetRoutes())) +}