Home  >  Article  >  Backend Development  >  Continue reading data after pausing for one second

Continue reading data after pausing for one second

WBOY
WBOYforward
2024-02-11 08:27:08377browse

Continue reading data after pausing for one second

php Editor Banana is here to share an interesting trick with you - "continue reading data after pausing for one second". In programming, sometimes we need to wait for a period of time before continuing to perform subsequent operations, and this technique can help us achieve this goal. Whether it is used for delayed operations of network requests, or to avoid certain time-consuming operations from affecting the execution efficiency of the program, this technique can play an important role. Below, we will introduce in detail how to implement this function in php.

Question content

I am using curl to get data from an endpoint and transfer it to the program. The main function of the program reads data like this

reader := bufio.NewReader(os.Stdin)
var buf bytes.Buffer
line, err := reader.ReadString(`\n`)
for {
  if err != nil{
     buf.WriteString(line)
     break
   }
  buf.WriteString(line)
}
var data Memstats
err = json.Unmarshal(buf.Bytes(), &data)

Everything is normal until here. However, my end goal is to repeatedly curl the endpoint like this for a period of time so that the program reads N JSON blobs arriving at N time intervals.

for i in {1..10}; do curl localhost:6000/debug/vars | ./myprogram; sleep 1; done

Every time you curl to the endpoint, you will arrive at the same structured data. So I have to move the data reading code into function readStdIn which I will call repeatedly until curl stops sending data and every time my program receives json data I will Unmarshal into a struct and add it to the slice. To call readStdIn repeatedly, I used a for loop, and to read the data in readStdIn, I also used a for loop. readStdIn The function never completes. why not?

The main function

for{
 reader := bufio.NewReader(os.Stdin)
 h.readStdIn(reader)
 time.Sleep(1 * time.Second)
 var err error
 //check to see if curl sent more data,  if not I break out of main function and continue on with program and hopefully an array full of Memstats
 newbytes, err := reader.ReadByte()
 if err != nil{
   break
 }

}

readStdIn function

func (rt *Graph)readStdIn(reader *bufio.Reader){
 var buf bytes.Buffer
 line, err := reader.ReadString('\n')
 for {
  if err != nil{
     if err == io.EOF{
        buf.WriteString(line)
        break
     }else{
       fmt.Println(err.Error())
       os.Exit(1)
     }
  }
 }
 buf.WriteString(line)
}
var data Memstats
err = json.Marshal(buf.Bytes(), &data)
rt.Memstats = append(rt.Memstats, &record)
}

Solution

For parsing JSON

You can also use the scanner by customizing the function or changing the bash script. But I believe both are more complex than the code below.

<code>package main

import (
    "encoding/json"
    "errors"
    "fmt"
    "io"
    "os"
)

func main() {
    fmt.Println("Start")
    decoder := json.NewDecoder(os.Stdin)
    for {
        var u User
        err := decoder.Decode(&u)

        if errors.Is(err, io.EOF) {
            fmt.Println("End")
            break
        }

        if err != nil {
            fmt.Println("Can not decode into json", err)
            continue
        }

        fmt.Println(u)
    }
}

type User struct {
    UserId int    `json:"userId"`
    Id     int    `json:"id"`
    Title  string `json:"title"`
}
</code>
<code>function repeatedCurl() {
  for i in $(seq 1 3); do
    # sleep 1 # optional you can emit
    curl -s "https://jsonplaceholder.typicode.com/posts/$i"
  done
}

repeatedCurl | ./foo
</code>

For newline separated data

<code>package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    fmt.Println("Start")
    scanner := bufio.NewScanner(bufio.NewReader(os.Stdin))
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
    fmt.Println("End")
}
</code>

It works for both creating new program instances (like your example) and normal pipe usage.

Use the same pipe

<code>function repeatedDateEcho() {
  while sleep 1; do
   echo "$(date)"
  done
}

repeatedDateEcho | ./myprogram
</code>

Output:

Start
Thu Jan 18 22:59:31 +03 2024
Thu Jan 18 22:59:32 +03 2024
Thu Jan 18 22:59:33 +03 2024
Thu Jan 18 22:59:34 +03 2024

Use different pipes (new instance each time)

while sleep 1; do echo "$(date)" | ./my program; complete Output:

Start
Thu Jan 18 22:58:46 +03 2024
End
Start
Thu Jan 18 22:58:47 +03 2024
End

The above is the detailed content of Continue reading data after pausing for one second. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete