Hi,

I have been learning Golang for some few months now but still find it 
difficult to design some applications. I have two HTTP servers A and B and 
would like to do the following
1. server A send an HTTP PUT request with JSON body to server B.
2. If server B is not available, server A retry until server B is up and 
respond to the request
3. In server B response body is a timer value received by server A  
4. Server B uses the timer value (eg 45) to send a PATCH request using the 
value as interval. For example in this case, server A send the PATCH 
request to server B every 45 seconds.
5. Server B respond to the PATCH request with either HTTP status code 204 
or status code 404.
6. If status code is 204, that is OK, server A continues to send the PATCH 
request using the 45 seconds interval.
7. If the response status is 404, server A have to start the process again 
from step 1 again to step 6 when 204 status code is received. 

I have tried to write some code which works but restarting from step 1 when 
404 status code is received does not work. Also am not sure if my 
application design is good enough. Any help and comments about my 
application design. Below is my code  

var (
    ContentLocation string
    Timer  int32
    mu      sync.Mutex
)

func SendPUTMessageToServerB() {
    
    msgbytes, err := ioutil.ReadFile("./msg.json")
    ...

    locProfilebytes, err := json.Marshal(pcfprofile)
  ...
 
    locVarNRFUrl := "server B url"

    profile, resp, err := HandlePUTMessage(locProfilebytes, locVarNRFUrl)

    status := resp.StatusCode
    
    if status == http.StatusOK {
        logrus.Println("PUT mesage Update SUCCESS")
    } else if status == http.StatusCreated {
        logrus.Println("PUT message SUCCESS")
    } else {

        logrus.Println(fmt.Errorf("Wrong status code returned by server B 
%d", status))
    }

    ContentLocation = resp.Header.Get("Location")
    Timer = profile.TimerValue
}

func HandlePUTMessage(filebyte []byte, VarPath string) (Profile, 
*http.Response, error) {

    var (
        // Set client and set url
        localVarHTTPMethod = http.MethodPut
        nfp          Profile
    )

    req, err := http.NewRequest(localVarHTTPMethod, VarPath, 
bytes.NewBuffer(filebyte))
    if err != nil {
        logrus.Error(err)
    }
    req.Close = true
    req.Header.Set("Content-Type", "application/json")

    backoff := 1
    for {
        res, err := Client.Do(req) 
        if err != nil || res == nil {
            logrus.Println("Server A Trying to send PUT request ...")
            backoff *= 2
            if backoff > 20 {
                backoff = 20
            }
            time.Sleep(time.Duration(backoff) * time.Second)
            continue
        }

        defer func() {
            if resCloseErr := res.Body.Close(); resCloseErr != nil {
                logrus.Errorf("Response body cannot close: %+v", 
resCloseErr)
            }
        }()

        bodybytes, err := ioutil.ReadAll(res.Body)
        //localVarHTTPResponse.Body.Close()
        if err != nil {
            logrus.Error(err)
            return nfp, res, err
        }

        json.Unmarshal(bodybytes, &nfp)
        return nfp, res, nil
    }
}

// Send PATCH message to server B 
func PATCHMessage() (err error) {
 ...

    patchitembytes, err := json.Marshal(patchitem)

    ...

    req, err := http.NewRequest("PATCH", ContentLocation, 
bytes.NewBuffer(patchitembytes))
    req.Header.Set("Content-Type", "application/json-patch+json")
    
    response, err := transport.Client.Do(req) // for dev

    defer response.Body.Close()

    status := response.StatusCode
    if status == http.StatusNoContent {
        
            logrus.Info("PATCH message SUCCESS")
    } else if status == http.StatusNotFound {

        // Here I would like to restart PUT message if status code is 404
        
        logrus.Println("Heart-Beat Message FAILED") 
    }
    return err
}

// Send a patch message every Timer value
func SendPATCHMessageEveryTimerValue() {

    for {
        ticker := time.NewTicker(time.Duration(Timer) * time.Second)
        mu.Lock()

        for _ = range ticker.C {
            err := PATCHMessage()
            if err != nil {
                SendPUTMessage()
            }
        }
        mu.Unlock()
    }
}


func main() {

    SendPUTMessageToServerB()
    go SendPATCHMessageEveryTimerValue()
}



-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a2481944-2a5c-467b-ba39-6e355fe219aan%40googlegroups.com.

Reply via email to