Coder Social home page Coder Social logo

bwlimit's Introduction

BWLimit

License Test Go Report Card Go Reference

BWLimit lets you configure a bandwidth limit on net.Conn, io.Reader and io.Writer.

Quick Start

BWLimit can be used to throttle the bandwidth (bytes per second) either on the client or server.

Install it with:

go get github.com/conduitio/bwlimit

See usage examples below:

Or check out the runnable examples.

Server Side

To limit the bandwidth on the server use bwlimit.NewListener.

package main

import (
	"io"
	"log"
	"net"
	"net/http"

	"github.com/conduitio/bwlimit"
)

const (
	writeLimit = 1 * bwlimit.Mebibyte // write limit is 1048576 B/s
	readLimit  = 4 * bwlimit.KB       // read limit is 4000 B/s
)

func main() {
	ln, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Fatalf("Failed to listen: %v", err)
	}
	// limit the listener bandwidth
	ln = bwlimit.NewListener(ln, writeLimit, readLimit)

	http.Handle("/echo", http.HandlerFunc(echoHandler))
	srv := &http.Server{Addr: addr}
	log.Fatalf("Failed to serve: %v", srv.Serve(ln))
}

func echoHandler(w http.ResponseWriter, r *http.Request) {
	body, _ := io.ReadAll(r.Body)
	_, _ = w.Write(body)
}

Client Side

To limit the bandwidth on the client use bwlimit.NewDialer.

package main

import (
	"io"
	"net"
	"net/http"
	"time"

	"github.com/conduitio/bwlimit"
)

const (
	writeLimit = 1 * bwlimit.Mebibyte // write limit is 1048576 B/s
	readLimit  = 4 * bwlimit.KB       // read limit is 4000 B/s
)

func main() {
	// change dialer in the default transport to use a bandwidth limit
	dialer := bwlimit.NewDialer(&net.Dialer{
		Timeout:   30 * time.Second,
		KeepAlive: 30 * time.Second,
	}, writeLimit, readLimit)
	http.DefaultTransport.(*http.Transport).DialContext = dialer.DialContext

	// requests through the default client respect the bandwidth limit now
	resp, _ := http.DefaultClient.Get("http://localhost:8080/echo")
	_, _ = io.ReadAll(resp.Body)
}

gRPC Client Interceptor

The gRPC interceptor is provided in a separate module, import it with:

go get github.com/conduitio/bwlimit/bwgrpc

To limit the bandwidth on a gRPC client use bwgrpc.WithBandwidthLimitedContextDialer.

package main

import (
	"context"
	"log"

	"github.com/conduitio/bwlimit"
	"github.com/conduitio/bwlimit/bwgrpc"
	"github.com/conduitio/bwlimit/bwgrpc/testproto"
	"google.golang.org/grpc"
)

const (
	writeLimit = 1 * bwlimit.Mebibyte // write limit is 1048576 B/s
	readLimit  = 4 * bwlimit.KB       // read limit is 4000 B/s
)

func main() {
	// open connection with limited bandwidth
	conn, err := grpc.DialContext(
		context.Background(),
		"localhost:8080",
		// limit the bandwidth
		bwgrpc.WithBandwidthLimitedContextDialer(writeLimit, readLimit, nil),
	)
	if err != nil {
		log.Fatalf("Failed to dial: %v", err)
	}
	defer conn.Close()

	// create gRPC client with the limited connection
	c := testproto.NewTestServiceClient(conn)
	
	// use client to send request
	_, err = c.TestRPC(ctx, &testproto.TestRequest{})
	if err != nil {
		log.Fatalf("Failed to send RPC: %v", err)
	}
}

Limitation

Please note that bwlimit limits the speed at which data is read from the local kernel's TCP buffer, and not directly from the remote connection. This means that the local buffer may become filled and cause the network to be idle while data is read slowly from the buffer, which can cause the actual bandwidth to differ from the one measured in Go code.

bwlimit's People

Contributors

lovromazgon avatar dependabot[bot] avatar limbo127 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.