Heim  >  Artikel  >  Backend-Entwicklung  >  Lesen Sie die Daten weiter, nachdem Sie eine Sekunde lang pausiert haben

Lesen Sie die Daten weiter, nachdem Sie eine Sekunde lang pausiert haben

WBOY
WBOYnach vorne
2024-02-11 08:27:08377Durchsuche

Lesen Sie die Daten weiter, nachdem Sie eine Sekunde lang pausiert haben

php-Editor Banana ist hier, um Ihnen einen interessanten Trick vorzustellen: „Lesen Sie die Daten weiter, nachdem Sie eine Sekunde lang pausiert haben“. Beim Programmieren müssen wir manchmal eine gewisse Zeit warten, bevor wir mit der Ausführung nachfolgender Vorgänge fortfahren. Diese Technik kann uns dabei helfen, dieses Ziel zu erreichen. Diese Technik kann eine wichtige Rolle spielen, unabhängig davon, ob sie für verzögerte Vorgänge bei Netzwerkanforderungen verwendet wird oder um zu vermeiden, dass bestimmte zeitaufwändige Vorgänge die Ausführungseffizienz des Programms beeinträchtigen. Im Folgenden stellen wir detailliert vor, wie diese Funktion in PHP implementiert wird.

Frageninhalt

Ich verwende Curl, um Daten von einem Endpunkt abzurufen und an mein Programm zu übertragen. Die Hauptfunktion des Programms liest solche Daten

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)

Bis hierher ist alles in Ordnung. Mein Endziel besteht jedoch darin, den Endpunkt über einen bestimmten Zeitraum wiederholt auf diese Weise zu locken, sodass das Programm N JSON-Blobs liest, die in N Zeitintervallen eintreffen.

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

Die gleichen strukturierten Daten werden nach jedem Einrollen zum Endpunkt erreicht. Also muss ich den Datenlesecode in eine Funktion verschieben readStdIn 中,我将重复调用该函数,直到curl 停止发送数据,并且每次我的程序接收到 json 数据时,我都会将其解组到结构中并将其添加到切片中。为了重复调用 readStdIn,我使用了 for 循环,为了读取 readStdIn 中的数据,我也使用了 for 循环。 readStdIn Die Funktion wird nie abgeschlossen. Warum nicht?

Hauptfunktionen

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-Funktion

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)
}

Workaround

für das Parsen von JSON

Sie können den Scanner auch verwenden, indem Sie Funktionen anpassen oder Bash-Skripte ändern. Ich glaube jedoch, dass beide komplexer sind als der folgende Code.

<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>

Für durch Zeilenumbrüche getrennte Daten

<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>

Es funktioniert sowohl beim Erstellen neuer Programminstanzen (wie in Ihrem Beispiel) als auch bei der normalen Pipe-Nutzung.

Verwenden Sie dieselbe Pipeline

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

repeatedDateEcho | ./myprogram
</code>

Ausgabe:

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

Verwenden Sie verschiedene Pipelines (jedes Mal eine neue Instanz)

while 睡眠 1;做 echo "$(date)" | ./我的程序;完成 Ausgabe:

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

Das obige ist der detaillierte Inhalt vonLesen Sie die Daten weiter, nachdem Sie eine Sekunde lang pausiert haben. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen