Commit 173de253 authored by Your Name's avatar Your Name

backup

parent 576700f2
package main
import (
"fmt"
"sync"
"time"
"github.com/segmentio/backo-go"
"github.com/shopspring/decimal"
"github.com/redis/go-redis/v9"
//"github.com/jehiah/go-strftime"
//"github.com/xtgo/uuid"
)
const (
RedisAddr = "localhost:6379"
RetryCount = 5
BatchSize = 1000
)
var Backo = backo.DefaultBacko()
var Bill *Metering
func init() {
Bill = NewMeteringClient()
}
type UserFee struct {
User string
Fee decimal.Decimal
}
// Metering message
type MeterMessage struct {
UniqueId string `json:"uniqueId"`
MeterApiName string `json:"meterApiName"`
CustomerId string `json:"customerId"`
MeterValue float64 `json:"meterValue"`
MeterTimeInMillis int64 `json:"meterTimeInMillis"`
}
// func ExampleClient() *redis.Client {
// url := "redis://user:password@localhost:6379/0?protocol=3"
// opts, err := redis.ParseURL(url)
// if err != nil {
// panic(err)
// }
// return redis.NewClient(opts)
// }
type MeteringOption func(*Metering)
func WithIntervalSeconds(intervalSeconds time.Duration) MeteringOption {
return func(m *Metering) {
m.IntervalSeconds = intervalSeconds
}
}
func WithBatchSize(batchSize int) MeteringOption {
return func(m *Metering) {
m.BatchSize = batchSize
}
}
type Metering struct {
//redisCli *redis.Client
// IntervalSeconds is the frequency at which messages are flushed.
dao *Dao
IntervalSeconds time.Duration
BatchSize int
// channels
msgs chan BillReq
quit chan struct{}
shutdown chan struct{}
// helper functions
uid func() string
now func() time.Time
// Synch primitives to control number of concurrent calls to API
once sync.Once
wg sync.WaitGroup
mutex sync.Mutex
upcond sync.Cond
counter int
}
// Create a new instance
func NewMeteringClient(opts ...MeteringOption) *Metering {
m := &Metering{
dao: &Dao{
redis.NewClient(&redis.Options{
Addr: RedisAddr,
Password: "", // no password set
DB: 0, // use default DB
Protocol: 3, // specify 2 for RESP 2 or 3 for RESP 3
}),
},
IntervalSeconds: 1 * time.Millisecond,
BatchSize: BatchSize,
msgs: make(chan BillReq, BatchSize),
quit: make(chan struct{}),
shutdown: make(chan struct{}),
now: time.Now,
}
//iterate through each option
for _, opt := range opts {
opt(m)
}
m.upcond.L = &m.mutex
return m
}
type BillReq struct {
Msg UserFee
Accept chan bool
}
// Queue a metering message to send to Ingest API. Messages are flushes periodically at IntervalSeconds or when the BatchSize limit is exceeded.
func (m *Metering) Meter(msg UserFee) bool {
fmt.Printf("Queuing meter message: %+v", msg)
m.once.Do(m.startLoop)
res := make(chan bool)
m.msgs <- BillReq{
Msg: msg,
Accept: res,
}
accept := <-res
return accept
}
// Start goroutine for concurrent execution to monitor channels
func (m *Metering) startLoop() {
go m.loop()
}
// // Queue the metering message
// func (m *Metering) queue(msg UserFee) {
// m.once.Do(m.startLoop)
// //send message to channel
// m.msgs <- msg
// }
// Flush all messages in the queue, stop the timer, close all channels, shutdown the client
func (m *Metering) Shutdown() error {
fmt.Println("Running shutdown....")
m.once.Do(m.startLoop)
//start shutdown by sending message to quit channel
m.quit <- struct{}{}
//close the ingest meter messages channel
close(m.msgs)
//receive shutdown message, blocking call
<-m.shutdown
fmt.Println("Shutdown completed")
return nil
}
// Sends batch to API asynchonrously and limits the number of concurrrent calls to API
func (m *Metering) sendAsync(msgs []BillReq) {
m.mutex.Lock()
//support 1000 asyncrhonus calls
for m.counter == 1000 {
//sleep until signal
m.upcond.Wait()
}
m.counter++
m.mutex.Unlock()
m.wg.Add(1)
//spin new thread to call API with retry
go func() {
err := m.send(msgs)
if err != nil {
fmt.Println(err.Error())
}
m.mutex.Lock()
m.counter--
//signal the waiting blocked wait
m.upcond.Signal()
m.mutex.Unlock()
m.wg.Done()
}()
}
// Send the batch request with retry
func (m *Metering) send(msgs []BillReq) error {
if len(msgs) == 0 {
return nil
}
//serialize to json
// b, err := json.Marshal(msgs)
// if err != nil {
// return fmt.Errorf("error marshalling msgs: %s", err)
// }
var err error
//retry attempts to call Ingest API
for i := 0; i < RetryCount; i++ {
if i > 0 {
fmt.Printf("Api call retry attempt: %d", i)
}
if err = m.dao.ReqRes(msgs); err == nil {
return nil
}
// if err = m.sendToRedis(msgs); err == nil {
// return nil
// }
fmt.Printf("Retry attempt: %d error: %s ", i, err.Error())
Backo.Sleep(i)
}
return err
}
// Run the listener loop in a separate thread to monitor all channels
func (m *Metering) loop() {
var msgs []BillReq
tick := time.NewTicker(m.IntervalSeconds)
fmt.Println("Listener thread and timer have started")
fmt.Printf("loop() ==> Effective batch size %d interval in seconds %d retry attempts %d", m.BatchSize, m.IntervalSeconds, RetryCount)
for {
//select to wait on multiple communication operations
//blocks until one of cases can run
select {
//process new meter message
case msg := <-m.msgs:
fmt.Printf("buffer (%d/%d) %v", len(msgs), m.BatchSize, msg)
msgs = append(msgs, msg)
if len(msgs) >= m.BatchSize {
fmt.Printf("exceeded %d messages – flushing", m.BatchSize)
m.sendAsync(msgs)
msgs = make([]BillReq, 0, m.BatchSize)
}
//timer event
case <-tick.C:
if len(msgs) > 0 {
fmt.Printf("interval reached - flushing %d", len(msgs))
m.sendAsync(msgs)
msgs = make([]BillReq, 0, m.BatchSize)
} else {
//fmt.Println("interval reached – nothing to send")
}
//process shutdown
case <-m.quit:
//stop the timer
tick.Stop()
//flush the queue
for msg := range m.msgs {
fmt.Printf("queue: (%d/%d) %v", len(msgs), m.BatchSize, msg)
msgs = append(msgs, msg)
}
fmt.Printf("Flushing %d messages", len(msgs))
m.sendAsync(msgs)
//wait for all messages to be sent to the API
m.wg.Wait()
fmt.Println("Queue flushed")
//let caller know shutdown is compelete
m.shutdown <- struct{}{}
return
}
}
}
......@@ -30,7 +30,7 @@ func req(uuid string) chan pbUpstream.TaskResponse {
func res(res pbUpstream.TaskResponse) {
if v, ok := recordmap.LoadAndDelete(res.TaskId); ok {
if v, ok := recordmap.LoadAndDelete(res.TaskUuid); ok {
resAsV, ok := v.(chan pbUpstream.TaskResponse)
if ok {
resAsV <- res
......
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
"github.com/shopspring/decimal"
)
type Dao struct {
*redis.Client
}
func (d *Dao) ReqRes(msgs []BillReq) error {
usersMap := make(map[string][]BillReq, len(msgs))
users := make([]string, 0, len(msgs))
for _, msg := range msgs {
if v, ok := usersMap[msg.Msg.User]; ok {
v = append(v, msg)
usersMap[msg.Msg.User] = v
} else {
userBillReq := make([]BillReq, 0, 10)
userBillReq = append(userBillReq, msg)
usersMap[msg.Msg.User] = userBillReq
users = append(users, msg.Msg.User)
}
}
usersBalance, err := d.GetBalanceSubCharge(users)
if err != nil {
return err
}
userCharge := make(map[string]decimal.Decimal, len(usersMap))
for k, v := range usersMap {
for _, billReq := range v {
if usersBalance[k].Cmp(billReq.Msg.Fee) == 1 {
if old, ok := userCharge[k]; ok {
userCharge[k] = old.Add(billReq.Msg.Fee)
} else {
userCharge[k] = billReq.Msg.Fee
}
}
}
}
if err := d.ChargeIncrby(context.Background(), userCharge); err != nil {
return err
}
for k, v := range usersMap {
for _, billReq := range v {
if usersBalance[k].Cmp(billReq.Msg.Fee) == 1 {
billReq.Accept <- true
} else {
billReq.Accept <- false
}
}
}
return nil
}
func (d *Dao) GetBalanceSubCharge(users []string) (map[string]decimal.Decimal, error) {
l := len(users)
balancekeys := make([]string, 0, l)
chargeKeys := make([]string, 0, l)
for _, user := range users {
balancekeys = append(balancekeys, "balance:"+user)
chargeKeys = append(chargeKeys, "charge:"+user)
}
vs := d.MGet(context.Background(), append(balancekeys, chargeKeys...)...)
res := make(map[string]decimal.Decimal, l)
redisValueRes := vs.Val()
for idx, v := range redisValueRes {
if idx == l {
break
}
fmt.Println("l", l, "idx", idx, "l+idx", l+idx, "len(redisValueRes)", len(redisValueRes), "v", v, "redisValueRes[l+idx]", redisValueRes[l+idx])
//if v != nil && redisValueRes[l+idx] != nil {
if balanceStr, ok := v.(string); ok {
balanceDec, err := decimal.NewFromString(balanceStr)
if err != nil {
fmt.Println("user balance error", users[idx], err.Error())
res[users[idx]] = decimal.NewFromInt(0)
continue
}
var chargeDec decimal.Decimal
if chargeStr, ok := redisValueRes[l+idx].(string); ok {
var err error
chargeDec, err = decimal.NewFromString(chargeStr)
if err != nil {
fmt.Println("user charge error", users[idx], err.Error())
res[users[idx]] = decimal.NewFromInt(0)
continue
}
} else {
chargeDec = decimal.NewFromInt(0)
}
if balanceDec.Cmp(chargeDec) == 1 {
realBalance := balanceDec.Sub(chargeDec)
//fmt.Println("user", users[idx], "balance", balanceDec, "charge", chargeDec, "realBalance", realBalance)
res[users[idx]] = realBalance
} else {
res[users[idx]] = decimal.NewFromInt(0)
}
continue
}
fmt.Println("user balance or charge is nil", "user", users[idx], "balance", v, "charge", redisValueRes[l+idx])
res[users[idx]] = decimal.NewFromInt(0)
continue
}
return res, nil
}
// INCRBY
func (d *Dao) ChargeIncrby(ctx context.Context, users map[string]decimal.Decimal) error {
pipe := d.Pipeline()
for user, fee := range users {
pipe.IncrBy(ctx, "charge:"+user, fee.IntPart())
}
_, err := pipe.Exec(ctx)
return err
}
package main
import (
"context"
"fmt"
"testing"
"github.com/redis/go-redis/v9"
"github.com/shopspring/decimal"
)
func TestRedis(t *testing.T) {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
Protocol: 3, // specify 2 for RESP 2 or 3 for RESP 3
})
vs := rdb.MGet(context.Background(), "key1", "key2")
for k, v := range vs.Val() {
fmt.Printf("idx %d value %v \n", k, v)
}
rdb.IncrBy(context.Background(), "key1", 10)
vs = rdb.MGet(context.Background(), "key1", "key2")
for k, v := range vs.Val() {
fmt.Printf("idx %d value %v type %T\n", k, v, v)
}
}
// func TestChargeIncreaseBy(t *testing.T) {
// d := &Dao{
// redis.NewClient(&redis.Options{
// Addr: "localhost:6379",
// Password: "", // no password set
// DB: 0, // use default DB
// Protocol: 3, // specify 2 for RESP 2 or 3 for RESP 3
// }),
// }
// usersFee := make([]UserFee, 0, 100)
// for i := 0; i < 10; i++ {
// usersFee = append(usersFee, UserFee{
// User: fmt.Sprintf("user-%v", i),
// Fee: decimal.NewFromInt(int64(i)),
// })
// }
// if err := d.ChargeIncrby(context.Background(), usersFee); err != nil {
// t.Fatal(err)
// }
// }
func TestBalanceIncreaseBy(t *testing.T) {
d := &Dao{
redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
Protocol: 3, // specify 2 for RESP 2 or 3 for RESP 3
}),
}
usersFee := make([]UserFee, 0, 100)
for i := 0; i < 10; i++ {
usersFee = append(usersFee, UserFee{
User: fmt.Sprintf("user-%v", i),
Fee: decimal.NewFromInt(int64(i * 10000000)),
})
}
if err := d.BalanceIncrby(context.Background(), usersFee); err != nil {
t.Fatal(err)
}
}
func (d *Dao) BalanceIncrby(ctx context.Context, users []UserFee) error {
pipe := d.Pipeline()
for _, user := range users {
pipe.IncrBy(ctx, "balance:"+user.User, user.Fee.IntPart())
}
_, err := pipe.Exec(ctx)
return err
}
func TestGetBalanceSubCharge(t *testing.T) {
d := &Dao{
redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
Protocol: 3, // specify 2 for RESP 2 or 3 for RESP 3
}),
}
usersFee := make([]string, 0, 100)
for i := 0; i < 30; i++ {
usersFee = append(usersFee, fmt.Sprintf("user-%v", i))
}
res, err := d.GetBalanceSubCharge(usersFee)
if err != nil {
t.Fatal(err)
}
for k, v := range res {
t.Logf("k %v v %v \n", k, v)
}
}
......@@ -2,27 +2,50 @@ version: '3.9'
services:
clickhouse:
image: clickhouse/clickhouse-server:23.3.9.55-alpine
container_name: clickhouse
ports:
- 8123:8123
- 9000:9000
- 9009:9009
environment:
CLICKHOUSE_USER: default
CLICKHOUSE_PASSWORD: default
CLICKHOUSE_DB: openmeter
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
ulimits:
nofile:
soft: 262144
hard: 262144
healthcheck:
test: wget --no-verbose --tries=1 --spider http://clickhouse:8123/ping || exit 1
interval: 5s
timeout: 3s
retries: 100
# clickhouse:
# image: clickhouse/clickhouse-server:23.3.9.55-alpine
# container_name: clickhouse
# ports:
# - 8123:8123
# - 9000:9000
# - 9009:9009
# environment:
# CLICKHOUSE_USER: default
# CLICKHOUSE_PASSWORD: default
# CLICKHOUSE_DB: task
# CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
# ulimits:
# nofile:
# soft: 262144
# hard: 262144
# healthcheck:
# test: wget --no-verbose --tries=1 --spider http://clickhouse:8123/ping || exit 1
# interval: 5s
# timeout: 3s
# retries: 100
# metabase:
# image: metabase/metabase:v0.48.1
# container_name: metabase-with-clickhouse-driver
# environment:
# 'MB_HTTP_TIMEOUT': '5000'
# 'JAVA_TIMEZONE': 'UTC'
# ports:
# - '3000:3000'
# volumes:
# - '../../../resources/modules/clickhouse.metabase-driver.jar:/plugins/clickhouse.jar'
# - './.docker/clickhouse/single_node_tls/certificates/ca.crt:/certs/ca.crt'
# metabase-clickhouse-driver
# clickhouse:
# image: 'clickhouse/clickhouse-server:23.8-alpine'
# container_name: 'metabase-clickhouse-server'
# ports:
# - '8123:8123'
# - '9000:9000'
# ulimits:
# nofile:
# soft: 262144
# hard: 262144
cloudbeaver:
image: dbeaver/cloudbeaver
......@@ -36,7 +59,7 @@ services:
image: grafana/grafana
container_name: "grafana-host"
ports:
- 3000:3000
- 3001:3000
restart: always
kafka:
image: blacktop/kafka:2.6
......
// Package docs Code generated by swaggo/swag. DO NOT EDIT
package docs
import "github.com/swaggo/swag"
const docTemplate = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"contact": {},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {}
}`
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "",
Host: "",
BasePath: "",
Schemes: []string{},
Title: "",
Description: "",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
LeftDelim: "{{",
RightDelim: "}}",
}
func init() {
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}
{
"swagger": "2.0",
"info": {
"contact": {}
},
"paths": {}
}
\ No newline at end of file
info:
contact: {}
paths: {}
swagger: "2.0"
......@@ -6,101 +6,78 @@ replace github.com/odysseus/odysseus-protocol => ../odysseus-protocol
replace github.com/odysseus/payment => ../payment
//replace github.com/ClickHouse/clickhouse-go => ../clickhouse-go
require (
// github.com/ClickHouse/clickhouse-go v1.5.4
github.com/IBM/sarama v1.42.1
github.com/gofiber/fiber/v2 v2.52.0
github.com/gogo/protobuf v1.3.2
github.com/odysseus/odysseus-protocol v0.0.0-00010101000000-000000000000
github.com/redis/go-redis/v9 v9.4.0
github.com/segmentio/backo-go v1.0.1
github.com/shopspring/decimal v1.3.1
github.com/odysseus/payment v0.0.0-00010101000000-000000000000
)
require github.com/ClickHouse/clickhouse-go/v2 v2.17.1
require (
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/ClickHouse/ch-go v0.58.2 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.1 // indirect
github.com/andybalholm/brotli v1.0.6 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/astaxie/beego v1.12.3 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/containerd/containerd v1.7.7 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/cpuguy83/dockercfg v0.3.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v24.0.7+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/eapache/go-resiliency v1.4.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.6.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/go-openapi/analysis v0.21.4 // indirect
github.com/go-openapi/errors v0.20.3 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.20.0 // indirect
github.com/go-openapi/loads v0.21.2 // indirect
github.com/go-openapi/runtime v0.26.0 // indirect
github.com/go-openapi/spec v0.20.8 // indirect
github.com/go-openapi/strfmt v0.21.7 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-openapi/validate v0.22.1 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/gofiber/contrib/swagger v1.1.1 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gomodule/redigo v2.0.0+incompatible // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
github.com/jcmturner/gofork v1.7.6 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/opencontainers/runc v1.1.5 // indirect
github.com/paulmach/orb v0.10.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/redis/go-redis/v9 v9.4.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/shirou/gopsutil/v3 v3.23.9 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/testcontainers/testcontainers-go v0.26.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.4.2 // indirect
github.com/swaggo/swag v1.16.2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.51.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/net v0.19.0 // indirect
go.mongodb.org/mongo-driver v1.11.3 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.7.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/grpc v1.60.1 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
module go-kafka
go 1.21.3
replace github.com/odysseus/odysseus-protocol => ../odysseus-protocol
replace github.com/odysseus/payment => ../payment
//replace github.com/ClickHouse/clickhouse-go => ../clickhouse-go
require (
// github.com/ClickHouse/clickhouse-go v1.5.4
github.com/IBM/sarama v1.42.1
github.com/gofiber/fiber/v2 v2.52.0
github.com/gogo/protobuf v1.3.2
github.com/odysseus/odysseus-protocol v0.0.0-00010101000000-000000000000
github.com/redis/go-redis/v9 v9.4.0
github.com/segmentio/backo-go v1.0.1
github.com/shopspring/decimal v1.3.1
)
require github.com/ClickHouse/clickhouse-go/v2 v2.17.1
require (
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/ClickHouse/ch-go v0.58.2 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.1 // indirect
github.com/andybalholm/brotli v1.0.6 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/containerd/containerd v1.7.7 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/cpuguy83/dockercfg v0.3.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v24.0.7+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/eapache/go-resiliency v1.4.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.6.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
github.com/jcmturner/gofork v1.7.6 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/odysseus/payment v0.0.0-00010101000000-000000000000 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/opencontainers/runc v1.1.5 // indirect
github.com/paulmach/orb v0.10.0 // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/shirou/gopsutil/v3 v3.23.9 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/testcontainers/testcontainers-go v0.26.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.51.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/tools v0.7.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/grpc v1.60.1 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
This diff is collapsed.
This diff is collapsed.
package main
import (
"log"
"github.com/gofiber/fiber/v2"
)
var logger = func(c *fiber.Ctx) {
log.Printf("Request: %s %s", c.Method(), c.Path())
c.Next()
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment