sponge

repository·main·Indexed 25 days ago

https://github.com/go-dev-frame/sponge

A Go development framework based on a 'Definition is Code' philosophy. It uses code generation to transform SQL, Protobuf, and JSON configurations into production-ready modular code for web services (Gin) and microservices (gRPC). It includes tools like protoc-gen-go-gin, protoc-gen-go-rpc-tmpl, and protoc-gen-json-field for generating routers, service templates, and JSON field mappings, as well as a perftest tool for performance testing.

Tokens
91.9K
Snippets
193
Records
431
Agent score
83%

What's inside sponge

  1. Overview of sasynq

    main

    sasynq is a Go wrapper around the asynq library, designed to provide a simpler SDK for asynchronous and distributed task processing.

    Key features include:

    • High Availability: Support for Redis Cluster and Sentinel.
    • Distributed Queues: Support for priority queues, delayed queues, unique tasks (to prevent duplicates), task cancellation, and periodic task scheduling.
    • Reliability: Built-in retry mechanisms (customizable counts), timeouts, and deadlines.
    • Scheduling: Flexible execution for immediate, delayed, or specific-time tasks.
    • Observability: Unified logging using zap.
  2. Overview of RabbitMQ client library

    main

    rabbitmq is a RabbitMQ client library for Go based on amqp091-go. It provides automatic reconnection support and customizable parameters. It supports six message types:

    1. Direct: Messages are routed to queues based on an exact match of the routing key.
    2. Topic: Messages are routed based on pattern matching between the routing key and the binding pattern.
    3. Fanout: Messages are broadcast to all queues bound to the exchange.
    4. Headers: Messages are routed based on attributes in the message header.
    5. Delayed Message: Supports sending messages with a specified delay.
    6. Publisher/Subscriber: A pattern for broadcasting messages to multiple subscribers via a channel.
  3. Overview of Google Service Control

    main
    Google Service Control provides control plane functionality for managed services, handling tasks like access control, logging, monitoring, and status checks. It offers a high-availability, scalable API accessible via JSON REST and gRPC. It is designed to allow service producers to send telemetry data to consumers without managing the underlying complexity of backend systems like Stackdriver Logging or Monitoring.
  4. Use the shield library for adaptive current limiting and circuit breaking

    main

    The shield package provides adaptive current limiting (rate limiting) and circuit breaker capabilities. It is based on the aegis library.

    To implement these features, refer to the specific sub-package documentation:

    • For rate limiting: See the ratelimit package.
    • For circuit breaking: See the circuitbreaker package.
  5. Implement mutual TLS (mTLS) connection with gtls

    main

    Use gtls to establish a mutual TLS (two-way) secure gRPC connection where both the server and the client verify each other using a common Certificate Authority (CA).

    On the server side, use GetServerTLSCredentialsByCA providing the CA certificate, the server certificate, and the server key.

    On the client side, use GetClientTLSCredentialsByCA providing the target server name, the CA certificate, the client certificate, and the client key.

    // Server side
    import "github.com/go-dev-frame/sponge/pkg/grpc/gtls"
    
    credentials, err := gtls.GetServerTLSCredentialsByCA(
        certfile.Path("two-way/ca.pem"),
        certfile.Path("two-way/server/server.pem"),
        certfile.Path("two-way/server/server.key"),
    )
    server := grpc.NewServer(grpc.Creds(credentials))
    
    // Client side
    import "github.com/go-dev-frame/sponge/pkg/grpc/gtls"
    
    credentials, err := gtls.GetClientTLSCredentialsByCA(
        "localhost",
        certfile.Path("two-way/ca.pem"),
        certfile.Path("two-way/client/client.pem"),
        certfile.Path("two-way/client/client.key"),
    )
    conn, err := grpc.NewClient("127.0.0.1:8080", grpc.WithTransportCredentials(credentials))
  6. Implement an SSE Client with Sponge

    main

    Use sse.NewClient(url) to create a client. Register event handlers using OnEvent(eventType, callback) and then call Connect() to establish the connection. The client supports automatic reconnection.

    package main
    
    import (
        "fmt"
        "github.com/go-dev-frame/sponge/pkg/sse"
    )
    
    func main() {
        url := "http://localhost:8080/events"
    
        // Create SSE client
        client := sse.NewClient(url)
    
        client.OnEvent(sse.DefaultEventType, func(event *sse.Event) {
            fmt.Printf("Received: %#v\n", event)
        })
    
        err := client.Connect()
        if err != nil {
            fmt.Printf("Connection failed: %v\n", err)
            return
        }
    
        fmt.Println("SSE client started, press Ctrl+C to exit")
        <-client.Wait()
    }
  7. Use the Sponge gRPC client to connect to a server

    main

    The client package provides a simplified way to establish gRPC connections in Go. Use client.NewClient(address, ...options) to create a connection. The function accepts several functional options to configure the client, including:

    • client.WithServiceDiscover(discovery, isPrimary): Configures service discovery.
    • client.WithLoadBalance(): Enables load balancing.
    • client.WithSecure(credentials): Configures secure connections using provided credentials.
    • client.WithUnaryInterceptor(unaryInterceptors...): Adds unary interceptors.
    • client.WithStreamInterceptor(streamInterceptors...): Adds stream interceptors.

    Once a connection (conn) is established, you can use it to initialize your generated gRPC client stubs.

    package main
    
    import (
        "context"
        "fmt"
        "github.com/go-dev-frame/sponge/pkg/grpc/client"
        pb "google.golang.org/grpc/examples/helloworld/helloworld"
    )
    
    func main() {
        // Initialize the connection with an address and optional configuration
        conn, err := client.NewClient("127.0.0.1:8282",
            // client.WithServiceDiscover(getDiscovery(), false),
            // client.WithLoadBalance(),
            // client.WithSecure(credentials),
            // client.WithUnaryInterceptor(unaryInterceptors...),
            // client.WithStreamInterceptor(streamInterceptors...),
        )
        if err != nil {
            panic(err)
        }
        defer conn.Close()
    
        // Use the connection to create a service client
        greeterClient := pb.NewGreeterClient(conn)
        reply, err := greeterClient.SayHello(context.Background(), &pb.HelloRequest{Name: "Alice"})
        if err != nil {
            panic(err)
        }
        fmt.Printf("Greeting: %s\n", reply.GetMessage())
    }
  8. Install Sponge on Windows

    main

    Sponge can be installed on Windows using an integrated installation package or via native Go installation.

    Prerequisites

    • Go Version: Requires Go 1.23+.
    • GOBIN Configuration: Ensure GOBIN is set and added to your system PATH. You can check this with go env GOBIN.
    1. Download the integrated package (contains all dependencies) from Baidu Netdisk or Lanzou Cloud (Password: 5rq9).
    2. Unzip the package and run install.bat.
    3. Important: Always use Git Bash to run Sponge commands. Do not use the default Windows cmd terminal, as it may result in 'command not found' errors.
    4. Open Git Bash (Right-click → Open Git Bash here) and run:
      sponge init          # Initialize and install dependencies
      sponge plugins       # View installed plugins
      sponge -v            # Check version

    Method 2: Native Installation

    Follow the standard Go installation procedure for Sponge as described in the official documentation.

  9. Parse configuration files using pkg/conf

    main

    The pkg/conf package allows you to parse YAML, JSON, or TOML configuration files directly into Go structs. It supports both static parsing and dynamic reloading with custom callback functions.

    import "github.com/go-dev-frame/sponge/pkg/conf"
    
    // Way 1: Static parsing (no file watching)
    config := &App{}
    err := conf.Parse("test.yml", config)
    
    // Way 2: Enable configuration file reloading
    config := &App{}
    reloads := []func(){
        func() {
            fmt.Println("close and reconnect mysql")
            fmt.Println("close and reconnect redis")
        },
    }
    err := conf.Parse("test.yml", config, reloads...)