Git Product home page Git Product logo

distributed-systems-ghc's Introduction

Building Resilient Distributed Systems With Golang

This repo is designed solely for the purpose of GHC'23 Level Up Lab titled 'Building Resilient Distributed Systems With Golang'.

Presenters:
1. Aayushi Chadha
2. Sanya Sharma
3. Utsha Sinha

Lab Prerequisites

1. Check if Go (Golang) is installed:

Open a terminal and run the following command:

go version

If Go is installed, you will see output that shows the Go version. If it's not installed, follow these instructions to install it:

  • Visit the official Go download page: https://golang.org/dl/
  • Download the installer for your operating system.
  • Follow the installation instructions for your specific OS.

2. Check if Docker is installed:

Run the following command in the terminal:

docker --version

If Docker is installed, it will display the Docker version. If it's not installed, follow these instructions to install it:

  • Visit the official Docker download page: https://docs.docker.com/get-docker/
  • Download the Docker Desktop for your operating system.
  • Install Docker following the installation instructions provided for your OS.

3. Check if Postman is installed:

Run the following command in the terminal:

postman --version

If Postman is installed, it will display the Postman version. If it's not installed, follow these instructions to install it:

Lab Activity 1:

1. Open your docker desktop app or run the following command

open -a Docker 

2. Run the docker compose command on the terminal

docker-compose up --build

3. Ensure the applications are up and running by looking at the docker logs

4. Import the postman collection

  • Open this link: Postman GHC Collection
  • Click on the three dots next to the GHC Collection and fork the collection
  • Open your Postman app, you should be able to view the collection. (Please ensure you are using the same login on the app and web view)

5. Test the Get Catalog API request

View the API response to see all the saree varieties available along with their description, retail price and quantity available

6. Test the Place Order API request

Navigate to the Payment Service. As you can see, the service retries each of the available payment gateway.

Lab Activity 2:

In this section, we'll be implementing the circuit breaker and add the relevant code to the payment/service/service.go file

1. Add the structure and map that implements the circuit breaker

    /* 
       CircuitBreaker implements the circuit breaker
       It has two fields:
        1. mu - Locks, Unlocks the instance of variable.
        2. open - Stores the state of circuit (open/close)
    */
    type CircuitBreaker struct {
        mu   sync.Mutex
        open bool
    }

    var circuitBreakerMap = map[string]*CircuitBreaker{}

  Note: Remember to add sync in import libraries.

2. Copy paste the following snippet for ExecuteTransaction, which executes the circuit breaker

    /* 
       ExecuteTransaction executes the payment transaction using circuit breaker.
       Given a certain number of failures happening in a payment gateway, 
       it'll stop retrying to avoid undue stress on the system and break open the circuit.
       Circuit will be reset after a certain interval of time.
    */
    func (cb *CircuitBreaker) ExecuteTransaction(operation func() bool, consecutiveFails int, paymentGateway string) bool {
        cb.mu.Lock()
        defer cb.mu.Unlock()
        
    }

3. Add the code to open the circuit if the number of consecutive failures is greater than the desired failure count

    completed := operation()

    if !completed {
        /* Add code here */
    }

    return completed

4. If the circuit is open, we will not attempt to call the gateway and return from the function before performing the operation.

    if cb.open {
        /* Add code here */
    }

5. Using goroutine, call the ResetAfterDelay function from ExecuteTransaction while opening the circuit so that it resets automatically after some time.

    // ResetAfterDelay resets the circuit after a delay.
    func (cb *CircuitBreaker) ResetAfterDelay(paymentGateway string) {
        /* Add code here */
    }
    

6. Modify the InitiatePayment function to call above circuit breaker code to execute payment

circuit, ok := circuitBreakerMap[paymentGateway]
if !ok {
    // Create a new CircuitBreaker for the payment gateway
    circuit = &CircuitBreaker{}
    circuitBreakerMap[paymentGateway] = circuit
}

var completed bool

for retry := 0; retry <= maxRetries; retry++ {
    if retry != 0 {
        /* 
            Loggin the retry 
            Add sleep before the next attempt
        */
        log.Printf("Payment gateway %v is unavailable. Retrying payment, attempt %d", paymentGateway, retry)
        time.Sleep(time.Second * time.Duration(retry))
    }

    completed = circuit.ExecuteTransaction(func() bool {
        return paymentContext.ExecutePayment()
    }, retry, paymentGateway)
    if completed {
        break
    }
}

7. Add more application level resilience
 We can add more fallback options for payment gateways for the situations when other options are unavailable. To do that, let's uncomment the remaining two payment gateways in payment/entity/entity.go.

PaymentGateways = []string{
    PaymentGatewayAmex,
    PaymentGatewayZakpay,
    PaymentGatewayWeiss,
    PaymentGatewayPaypal,
}

8. Re-run the service and try placing order now

** 9. Sample requests**
GetCatalog API
GET call
URL:

localhost:8083/get-catalog


PlaceOrder API
POST call
URL:
localhost:8080/place-order

Body

{ "customer_id": 3, "product_id": 3, "quantity": 4 }

distributed-systems-ghc's People

Contributors

sanya-sharma avatar utsha1510 avatar sanya-sha avatar achadha16 avatar oots-1510 avatar aayushichadha 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.