How to delay a live stream?How to efficiently concatenate strings in Go?How to check if a map contains a key in go?In Go, if type T2 is based on type T1, is there any sort of “inheritance” from T1 to T2?How do you write multiline strings in Go?Go Nonblocking multiple receive on channelHow to determine which side of go channel is waiting?Range a channel finishes with deadlockHow to wait for *any* of a group of goroutines to signal something without requiring that we wait for them to do soConfused about channel argument for GoroutinesSignal goroutines to stop with channel close

What is the best translation for "slot" in the context of multiplayer video games?

Implement the Thanos sorting algorithm

Pole-zeros of a real-valued causal FIR system

How does Loki do this?

Short story about space worker geeks who zone out by 'listening' to radiation from stars

Lay out the Carpet

Applicability of Single Responsibility Principle

How do I go from 300 unfinished/half written blog posts, to published posts?

Do sorcerers' Subtle Spells require a skill check to be unseen?

Increase performance creating Mandelbrot set in python

Why are there no referendums in the US?

Flow chart document symbol

Opposite of a diet

Efficient way to transport a Stargate

Why didn't Theresa May consult with Parliament before negotiating a deal with the EU?

Replace character with another only if repeated and not part of a word

Large drywall patch supports

Did Dumbledore lie to Harry about how long he had James Potter's invisibility cloak when he was examining it? If so, why?

A problem in Probability theory

Would this custom Sorcerer variant that can only learn any verbal-component-only spell be unbalanced?

Is HostGator storing my password in plaintext?

How to write papers efficiently when English isn't my first language?

Crossing the line between justified force and brutality

Two monoidal structures and copowering



How to delay a live stream?


How to efficiently concatenate strings in Go?How to check if a map contains a key in go?In Go, if type T2 is based on type T1, is there any sort of “inheritance” from T1 to T2?How do you write multiline strings in Go?Go Nonblocking multiple receive on channelHow to determine which side of go channel is waiting?Range a channel finishes with deadlockHow to wait for *any* of a group of goroutines to signal something without requiring that we wait for them to do soConfused about channel argument for GoroutinesSignal goroutines to stop with channel close













2















I'm trying to build a service in Go which delays a live stream (socketio/signalR) for ~7 minutes. It should also allow a non-delayed stream. So the Go service should have something like a buffer or a queue that forces data to wait for the specified duration before it is allowed to be consumed. How would you do something like this in Go? Would the delayed stream be a seperate goroutine? What data structure should be used to delay the data?



My current idea would be to use the time package to wait/tick for 7 minutes before the data is allowed to be consumed but this blocking behavior might not be optimal in this scenario.



Here is some code to explain what I'm trying to do. FakeStream is a mock function that simulates the live streamed data I'm getting from the external service.



package main

import (
"fmt"
"time"
)

func DelayStream(input chan string, output chan string, delay string)

// not working for some reason
// delayDuration, _ := time.ParseDuration(delay)
// fmt.Println(delayDuration.Seconds())

if delay == "5s"
fmt.Println("sleeping")
time.Sleep(5 * time.Second)

data := <-input
output <- data


func FakeStream(live chan string)

ticks := time.Tick(2 * time.Second)
for now := range ticks
live <- fmt.Sprintf("%v", now.Format(time.UnixDate))



func main()
liveData := make(chan string)
delayedData := make(chan string)

go FakeStream(liveData)
go DelayStream(liveData, delayedData, "5s")

for
select
case live := <-liveData:
fmt.Println("live: ", live)
case delayed := <-delayedData:
fmt.Println("delayed: ", delayed)





For some reason the delayed channel only outputs once and it doesn't output the expected data. It should output the first thing in the live channel but it doesn't.










share|improve this question
























  • Can you share your code snippet to make your methodology clearer to people around here?

    – vahdet
    Mar 8 at 11:38











  • Adding a delay to code is easy. Write something, when you get stuck, then ask here, and include your code.

    – Flimzy
    Mar 8 at 11:42











  • @flimzy Added some code

    – ninesalt
    Mar 8 at 11:57















2















I'm trying to build a service in Go which delays a live stream (socketio/signalR) for ~7 minutes. It should also allow a non-delayed stream. So the Go service should have something like a buffer or a queue that forces data to wait for the specified duration before it is allowed to be consumed. How would you do something like this in Go? Would the delayed stream be a seperate goroutine? What data structure should be used to delay the data?



My current idea would be to use the time package to wait/tick for 7 minutes before the data is allowed to be consumed but this blocking behavior might not be optimal in this scenario.



Here is some code to explain what I'm trying to do. FakeStream is a mock function that simulates the live streamed data I'm getting from the external service.



package main

import (
"fmt"
"time"
)

func DelayStream(input chan string, output chan string, delay string)

// not working for some reason
// delayDuration, _ := time.ParseDuration(delay)
// fmt.Println(delayDuration.Seconds())

if delay == "5s"
fmt.Println("sleeping")
time.Sleep(5 * time.Second)

data := <-input
output <- data


func FakeStream(live chan string)

ticks := time.Tick(2 * time.Second)
for now := range ticks
live <- fmt.Sprintf("%v", now.Format(time.UnixDate))



func main()
liveData := make(chan string)
delayedData := make(chan string)

go FakeStream(liveData)
go DelayStream(liveData, delayedData, "5s")

for
select
case live := <-liveData:
fmt.Println("live: ", live)
case delayed := <-delayedData:
fmt.Println("delayed: ", delayed)





For some reason the delayed channel only outputs once and it doesn't output the expected data. It should output the first thing in the live channel but it doesn't.










share|improve this question
























  • Can you share your code snippet to make your methodology clearer to people around here?

    – vahdet
    Mar 8 at 11:38











  • Adding a delay to code is easy. Write something, when you get stuck, then ask here, and include your code.

    – Flimzy
    Mar 8 at 11:42











  • @flimzy Added some code

    – ninesalt
    Mar 8 at 11:57













2












2








2








I'm trying to build a service in Go which delays a live stream (socketio/signalR) for ~7 minutes. It should also allow a non-delayed stream. So the Go service should have something like a buffer or a queue that forces data to wait for the specified duration before it is allowed to be consumed. How would you do something like this in Go? Would the delayed stream be a seperate goroutine? What data structure should be used to delay the data?



My current idea would be to use the time package to wait/tick for 7 minutes before the data is allowed to be consumed but this blocking behavior might not be optimal in this scenario.



Here is some code to explain what I'm trying to do. FakeStream is a mock function that simulates the live streamed data I'm getting from the external service.



package main

import (
"fmt"
"time"
)

func DelayStream(input chan string, output chan string, delay string)

// not working for some reason
// delayDuration, _ := time.ParseDuration(delay)
// fmt.Println(delayDuration.Seconds())

if delay == "5s"
fmt.Println("sleeping")
time.Sleep(5 * time.Second)

data := <-input
output <- data


func FakeStream(live chan string)

ticks := time.Tick(2 * time.Second)
for now := range ticks
live <- fmt.Sprintf("%v", now.Format(time.UnixDate))



func main()
liveData := make(chan string)
delayedData := make(chan string)

go FakeStream(liveData)
go DelayStream(liveData, delayedData, "5s")

for
select
case live := <-liveData:
fmt.Println("live: ", live)
case delayed := <-delayedData:
fmt.Println("delayed: ", delayed)





For some reason the delayed channel only outputs once and it doesn't output the expected data. It should output the first thing in the live channel but it doesn't.










share|improve this question
















I'm trying to build a service in Go which delays a live stream (socketio/signalR) for ~7 minutes. It should also allow a non-delayed stream. So the Go service should have something like a buffer or a queue that forces data to wait for the specified duration before it is allowed to be consumed. How would you do something like this in Go? Would the delayed stream be a seperate goroutine? What data structure should be used to delay the data?



My current idea would be to use the time package to wait/tick for 7 minutes before the data is allowed to be consumed but this blocking behavior might not be optimal in this scenario.



Here is some code to explain what I'm trying to do. FakeStream is a mock function that simulates the live streamed data I'm getting from the external service.



package main

import (
"fmt"
"time"
)

func DelayStream(input chan string, output chan string, delay string)

// not working for some reason
// delayDuration, _ := time.ParseDuration(delay)
// fmt.Println(delayDuration.Seconds())

if delay == "5s"
fmt.Println("sleeping")
time.Sleep(5 * time.Second)

data := <-input
output <- data


func FakeStream(live chan string)

ticks := time.Tick(2 * time.Second)
for now := range ticks
live <- fmt.Sprintf("%v", now.Format(time.UnixDate))



func main()
liveData := make(chan string)
delayedData := make(chan string)

go FakeStream(liveData)
go DelayStream(liveData, delayedData, "5s")

for
select
case live := <-liveData:
fmt.Println("live: ", live)
case delayed := <-delayedData:
fmt.Println("delayed: ", delayed)





For some reason the delayed channel only outputs once and it doesn't output the expected data. It should output the first thing in the live channel but it doesn't.







go






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 8 at 12:43







ninesalt

















asked Mar 8 at 11:34









ninesaltninesalt

1,46511230




1,46511230












  • Can you share your code snippet to make your methodology clearer to people around here?

    – vahdet
    Mar 8 at 11:38











  • Adding a delay to code is easy. Write something, when you get stuck, then ask here, and include your code.

    – Flimzy
    Mar 8 at 11:42











  • @flimzy Added some code

    – ninesalt
    Mar 8 at 11:57

















  • Can you share your code snippet to make your methodology clearer to people around here?

    – vahdet
    Mar 8 at 11:38











  • Adding a delay to code is easy. Write something, when you get stuck, then ask here, and include your code.

    – Flimzy
    Mar 8 at 11:42











  • @flimzy Added some code

    – ninesalt
    Mar 8 at 11:57
















Can you share your code snippet to make your methodology clearer to people around here?

– vahdet
Mar 8 at 11:38





Can you share your code snippet to make your methodology clearer to people around here?

– vahdet
Mar 8 at 11:38













Adding a delay to code is easy. Write something, when you get stuck, then ask here, and include your code.

– Flimzy
Mar 8 at 11:42





Adding a delay to code is easy. Write something, when you get stuck, then ask here, and include your code.

– Flimzy
Mar 8 at 11:42













@flimzy Added some code

– ninesalt
Mar 8 at 11:57





@flimzy Added some code

– ninesalt
Mar 8 at 11:57












1 Answer
1






active

oldest

votes


















3














You need a buffer of sufficient size. For simple cases, a buffered Go channel could work.



Ask yourself - how much data is there to store during this delay - you should have a reasonable upper cap. For example if your stream delivers up to N packets per second, then to delay by 7 minutes you'll need to store 420N packets.



Ask yourself - what happens if more data than expected arrives during the delay window? You can throw the new data away, or throw the old data away, or just block the input stream. Which of these are feasible for your scenario? Each results in a slightly different solution.



Ask yourself - how is the delay computed? From the moment the stream is created? From the moment each packet arrives? Is the delay for each packet separately, or only for the first packet in the stream?



You'll need to considerably narrow down the design choices here in order to develop some sample code.



For some subset of these design choices, here's a simple way to add delay between channels for each message:




package main

import (
"fmt"
"sync"
"time"
)

func main()
// in is a channel of strings with a buffer size of 10
in := make(chan string, 10)

// out is an unbuffered channel
out := make(chan string)

// this goroutine forwards messages from in to out, ading a delay
// to each message.
const delay = 3 * time.Second
go func()
for msg := range in
time.Sleep(delay)
out <- msg

close(out)
()

var wg sync.WaitGroup
wg.Add(1)
// this goroutine drains the out channel
go func()
for msg := range out
fmt.Printf("Got '%s' at time %sn", msg, time.Now().Format(time.Stamp))

wg.Done()
()

// Send some messages into the in channel
fmt.Printf("Sending '%s' at time %sn", "joe", time.Now().Format(time.Stamp))
in <- "joe"

time.Sleep(2 * time.Second)
fmt.Printf("Sending '%s' at time %sn", "hello", time.Now().Format(time.Stamp))
in <- "hello"

time.Sleep(4 * time.Second)
fmt.Printf("Sending '%s' at time %sn", "bye", time.Now().Format(time.Stamp))
in <- "bye"
close(in)

wg.Wait()






share|improve this answer

























  • Can you explain why you're using the WaitGroup?

    – ninesalt
    Mar 8 at 15:13






  • 1





    waitGroups are a key tool for coordinating go-routines. In the above case, tracing the wg references, the main function will not exit, until the go func() go-routine has completed. In a standalone executable example like this, this is crucial, as the program will just quickly exit - if the main go-routine exits. In this example the delay go-routine is still running - so it's polite to let it finish.

    – colminator
    Mar 8 at 15:32











  • @colminator But why does the first goroutine ignore this?

    – ninesalt
    Mar 8 at 15:34











  • go-routines are completely independent by design. For a useful program, one needs coordination. Go-routines can communicate via channels, waitGroups, locks etc., or not at all - it's up to you.

    – colminator
    Mar 8 at 15:36











  • Also how would I change this to allow two functions to read from the same channel? As mentioned in the OP, the live data should also be streamed. My current solution is not working too well.

    – ninesalt
    Mar 8 at 15:37










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55062416%2fhow-to-delay-a-live-stream%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














You need a buffer of sufficient size. For simple cases, a buffered Go channel could work.



Ask yourself - how much data is there to store during this delay - you should have a reasonable upper cap. For example if your stream delivers up to N packets per second, then to delay by 7 minutes you'll need to store 420N packets.



Ask yourself - what happens if more data than expected arrives during the delay window? You can throw the new data away, or throw the old data away, or just block the input stream. Which of these are feasible for your scenario? Each results in a slightly different solution.



Ask yourself - how is the delay computed? From the moment the stream is created? From the moment each packet arrives? Is the delay for each packet separately, or only for the first packet in the stream?



You'll need to considerably narrow down the design choices here in order to develop some sample code.



For some subset of these design choices, here's a simple way to add delay between channels for each message:




package main

import (
"fmt"
"sync"
"time"
)

func main()
// in is a channel of strings with a buffer size of 10
in := make(chan string, 10)

// out is an unbuffered channel
out := make(chan string)

// this goroutine forwards messages from in to out, ading a delay
// to each message.
const delay = 3 * time.Second
go func()
for msg := range in
time.Sleep(delay)
out <- msg

close(out)
()

var wg sync.WaitGroup
wg.Add(1)
// this goroutine drains the out channel
go func()
for msg := range out
fmt.Printf("Got '%s' at time %sn", msg, time.Now().Format(time.Stamp))

wg.Done()
()

// Send some messages into the in channel
fmt.Printf("Sending '%s' at time %sn", "joe", time.Now().Format(time.Stamp))
in <- "joe"

time.Sleep(2 * time.Second)
fmt.Printf("Sending '%s' at time %sn", "hello", time.Now().Format(time.Stamp))
in <- "hello"

time.Sleep(4 * time.Second)
fmt.Printf("Sending '%s' at time %sn", "bye", time.Now().Format(time.Stamp))
in <- "bye"
close(in)

wg.Wait()






share|improve this answer

























  • Can you explain why you're using the WaitGroup?

    – ninesalt
    Mar 8 at 15:13






  • 1





    waitGroups are a key tool for coordinating go-routines. In the above case, tracing the wg references, the main function will not exit, until the go func() go-routine has completed. In a standalone executable example like this, this is crucial, as the program will just quickly exit - if the main go-routine exits. In this example the delay go-routine is still running - so it's polite to let it finish.

    – colminator
    Mar 8 at 15:32











  • @colminator But why does the first goroutine ignore this?

    – ninesalt
    Mar 8 at 15:34











  • go-routines are completely independent by design. For a useful program, one needs coordination. Go-routines can communicate via channels, waitGroups, locks etc., or not at all - it's up to you.

    – colminator
    Mar 8 at 15:36











  • Also how would I change this to allow two functions to read from the same channel? As mentioned in the OP, the live data should also be streamed. My current solution is not working too well.

    – ninesalt
    Mar 8 at 15:37















3














You need a buffer of sufficient size. For simple cases, a buffered Go channel could work.



Ask yourself - how much data is there to store during this delay - you should have a reasonable upper cap. For example if your stream delivers up to N packets per second, then to delay by 7 minutes you'll need to store 420N packets.



Ask yourself - what happens if more data than expected arrives during the delay window? You can throw the new data away, or throw the old data away, or just block the input stream. Which of these are feasible for your scenario? Each results in a slightly different solution.



Ask yourself - how is the delay computed? From the moment the stream is created? From the moment each packet arrives? Is the delay for each packet separately, or only for the first packet in the stream?



You'll need to considerably narrow down the design choices here in order to develop some sample code.



For some subset of these design choices, here's a simple way to add delay between channels for each message:




package main

import (
"fmt"
"sync"
"time"
)

func main()
// in is a channel of strings with a buffer size of 10
in := make(chan string, 10)

// out is an unbuffered channel
out := make(chan string)

// this goroutine forwards messages from in to out, ading a delay
// to each message.
const delay = 3 * time.Second
go func()
for msg := range in
time.Sleep(delay)
out <- msg

close(out)
()

var wg sync.WaitGroup
wg.Add(1)
// this goroutine drains the out channel
go func()
for msg := range out
fmt.Printf("Got '%s' at time %sn", msg, time.Now().Format(time.Stamp))

wg.Done()
()

// Send some messages into the in channel
fmt.Printf("Sending '%s' at time %sn", "joe", time.Now().Format(time.Stamp))
in <- "joe"

time.Sleep(2 * time.Second)
fmt.Printf("Sending '%s' at time %sn", "hello", time.Now().Format(time.Stamp))
in <- "hello"

time.Sleep(4 * time.Second)
fmt.Printf("Sending '%s' at time %sn", "bye", time.Now().Format(time.Stamp))
in <- "bye"
close(in)

wg.Wait()






share|improve this answer

























  • Can you explain why you're using the WaitGroup?

    – ninesalt
    Mar 8 at 15:13






  • 1





    waitGroups are a key tool for coordinating go-routines. In the above case, tracing the wg references, the main function will not exit, until the go func() go-routine has completed. In a standalone executable example like this, this is crucial, as the program will just quickly exit - if the main go-routine exits. In this example the delay go-routine is still running - so it's polite to let it finish.

    – colminator
    Mar 8 at 15:32











  • @colminator But why does the first goroutine ignore this?

    – ninesalt
    Mar 8 at 15:34











  • go-routines are completely independent by design. For a useful program, one needs coordination. Go-routines can communicate via channels, waitGroups, locks etc., or not at all - it's up to you.

    – colminator
    Mar 8 at 15:36











  • Also how would I change this to allow two functions to read from the same channel? As mentioned in the OP, the live data should also be streamed. My current solution is not working too well.

    – ninesalt
    Mar 8 at 15:37













3












3








3







You need a buffer of sufficient size. For simple cases, a buffered Go channel could work.



Ask yourself - how much data is there to store during this delay - you should have a reasonable upper cap. For example if your stream delivers up to N packets per second, then to delay by 7 minutes you'll need to store 420N packets.



Ask yourself - what happens if more data than expected arrives during the delay window? You can throw the new data away, or throw the old data away, or just block the input stream. Which of these are feasible for your scenario? Each results in a slightly different solution.



Ask yourself - how is the delay computed? From the moment the stream is created? From the moment each packet arrives? Is the delay for each packet separately, or only for the first packet in the stream?



You'll need to considerably narrow down the design choices here in order to develop some sample code.



For some subset of these design choices, here's a simple way to add delay between channels for each message:




package main

import (
"fmt"
"sync"
"time"
)

func main()
// in is a channel of strings with a buffer size of 10
in := make(chan string, 10)

// out is an unbuffered channel
out := make(chan string)

// this goroutine forwards messages from in to out, ading a delay
// to each message.
const delay = 3 * time.Second
go func()
for msg := range in
time.Sleep(delay)
out <- msg

close(out)
()

var wg sync.WaitGroup
wg.Add(1)
// this goroutine drains the out channel
go func()
for msg := range out
fmt.Printf("Got '%s' at time %sn", msg, time.Now().Format(time.Stamp))

wg.Done()
()

// Send some messages into the in channel
fmt.Printf("Sending '%s' at time %sn", "joe", time.Now().Format(time.Stamp))
in <- "joe"

time.Sleep(2 * time.Second)
fmt.Printf("Sending '%s' at time %sn", "hello", time.Now().Format(time.Stamp))
in <- "hello"

time.Sleep(4 * time.Second)
fmt.Printf("Sending '%s' at time %sn", "bye", time.Now().Format(time.Stamp))
in <- "bye"
close(in)

wg.Wait()






share|improve this answer















You need a buffer of sufficient size. For simple cases, a buffered Go channel could work.



Ask yourself - how much data is there to store during this delay - you should have a reasonable upper cap. For example if your stream delivers up to N packets per second, then to delay by 7 minutes you'll need to store 420N packets.



Ask yourself - what happens if more data than expected arrives during the delay window? You can throw the new data away, or throw the old data away, or just block the input stream. Which of these are feasible for your scenario? Each results in a slightly different solution.



Ask yourself - how is the delay computed? From the moment the stream is created? From the moment each packet arrives? Is the delay for each packet separately, or only for the first packet in the stream?



You'll need to considerably narrow down the design choices here in order to develop some sample code.



For some subset of these design choices, here's a simple way to add delay between channels for each message:




package main

import (
"fmt"
"sync"
"time"
)

func main()
// in is a channel of strings with a buffer size of 10
in := make(chan string, 10)

// out is an unbuffered channel
out := make(chan string)

// this goroutine forwards messages from in to out, ading a delay
// to each message.
const delay = 3 * time.Second
go func()
for msg := range in
time.Sleep(delay)
out <- msg

close(out)
()

var wg sync.WaitGroup
wg.Add(1)
// this goroutine drains the out channel
go func()
for msg := range out
fmt.Printf("Got '%s' at time %sn", msg, time.Now().Format(time.Stamp))

wg.Done()
()

// Send some messages into the in channel
fmt.Printf("Sending '%s' at time %sn", "joe", time.Now().Format(time.Stamp))
in <- "joe"

time.Sleep(2 * time.Second)
fmt.Printf("Sending '%s' at time %sn", "hello", time.Now().Format(time.Stamp))
in <- "hello"

time.Sleep(4 * time.Second)
fmt.Printf("Sending '%s' at time %sn", "bye", time.Now().Format(time.Stamp))
in <- "bye"
close(in)

wg.Wait()







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 8 at 14:19

























answered Mar 8 at 13:59









Eli BenderskyEli Bendersky

169k71299373




169k71299373












  • Can you explain why you're using the WaitGroup?

    – ninesalt
    Mar 8 at 15:13






  • 1





    waitGroups are a key tool for coordinating go-routines. In the above case, tracing the wg references, the main function will not exit, until the go func() go-routine has completed. In a standalone executable example like this, this is crucial, as the program will just quickly exit - if the main go-routine exits. In this example the delay go-routine is still running - so it's polite to let it finish.

    – colminator
    Mar 8 at 15:32











  • @colminator But why does the first goroutine ignore this?

    – ninesalt
    Mar 8 at 15:34











  • go-routines are completely independent by design. For a useful program, one needs coordination. Go-routines can communicate via channels, waitGroups, locks etc., or not at all - it's up to you.

    – colminator
    Mar 8 at 15:36











  • Also how would I change this to allow two functions to read from the same channel? As mentioned in the OP, the live data should also be streamed. My current solution is not working too well.

    – ninesalt
    Mar 8 at 15:37

















  • Can you explain why you're using the WaitGroup?

    – ninesalt
    Mar 8 at 15:13






  • 1





    waitGroups are a key tool for coordinating go-routines. In the above case, tracing the wg references, the main function will not exit, until the go func() go-routine has completed. In a standalone executable example like this, this is crucial, as the program will just quickly exit - if the main go-routine exits. In this example the delay go-routine is still running - so it's polite to let it finish.

    – colminator
    Mar 8 at 15:32











  • @colminator But why does the first goroutine ignore this?

    – ninesalt
    Mar 8 at 15:34











  • go-routines are completely independent by design. For a useful program, one needs coordination. Go-routines can communicate via channels, waitGroups, locks etc., or not at all - it's up to you.

    – colminator
    Mar 8 at 15:36











  • Also how would I change this to allow two functions to read from the same channel? As mentioned in the OP, the live data should also be streamed. My current solution is not working too well.

    – ninesalt
    Mar 8 at 15:37
















Can you explain why you're using the WaitGroup?

– ninesalt
Mar 8 at 15:13





Can you explain why you're using the WaitGroup?

– ninesalt
Mar 8 at 15:13




1




1





waitGroups are a key tool for coordinating go-routines. In the above case, tracing the wg references, the main function will not exit, until the go func() go-routine has completed. In a standalone executable example like this, this is crucial, as the program will just quickly exit - if the main go-routine exits. In this example the delay go-routine is still running - so it's polite to let it finish.

– colminator
Mar 8 at 15:32





waitGroups are a key tool for coordinating go-routines. In the above case, tracing the wg references, the main function will not exit, until the go func() go-routine has completed. In a standalone executable example like this, this is crucial, as the program will just quickly exit - if the main go-routine exits. In this example the delay go-routine is still running - so it's polite to let it finish.

– colminator
Mar 8 at 15:32













@colminator But why does the first goroutine ignore this?

– ninesalt
Mar 8 at 15:34





@colminator But why does the first goroutine ignore this?

– ninesalt
Mar 8 at 15:34













go-routines are completely independent by design. For a useful program, one needs coordination. Go-routines can communicate via channels, waitGroups, locks etc., or not at all - it's up to you.

– colminator
Mar 8 at 15:36





go-routines are completely independent by design. For a useful program, one needs coordination. Go-routines can communicate via channels, waitGroups, locks etc., or not at all - it's up to you.

– colminator
Mar 8 at 15:36













Also how would I change this to allow two functions to read from the same channel? As mentioned in the OP, the live data should also be streamed. My current solution is not working too well.

– ninesalt
Mar 8 at 15:37





Also how would I change this to allow two functions to read from the same channel? As mentioned in the OP, the live data should also be streamed. My current solution is not working too well.

– ninesalt
Mar 8 at 15:37



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55062416%2fhow-to-delay-a-live-stream%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Can't initialize raids on a new ASUS Prime B360M-A motherboard2019 Community Moderator ElectionSimilar to RAID config yet more like mirroring solution?Can't get motherboard serial numberWhy does the BIOS entry point start with a WBINVD instruction?UEFI performance Asus Maximus V Extreme

Identity Server 4 is not redirecting to Angular app after login2019 Community Moderator ElectionIdentity Server 4 and dockerIdentityserver implicit flow unauthorized_clientIdentityServer Hybrid Flow - Access Token is null after user successful loginIdentity Server to MVC client : Page Redirect After loginLogin with Steam OpenId(oidc-client-js)Identity Server 4+.NET Core 2.0 + IdentityIdentityServer4 post-login redirect not working in Edge browserCall to IdentityServer4 generates System.NullReferenceException: Object reference not set to an instance of an objectIdentityServer4 without HTTPS not workingHow to get Authorization code from identity server without login form

2005 Ahvaz unrest Contents Background Causes Casualties Aftermath See also References Navigation menue"At Least 10 Are Killed by Bombs in Iran""Iran"Archived"Arab-Iranians in Iran to make April 15 'Day of Fury'"State of Mind, State of Order: Reactions to Ethnic Unrest in the Islamic Republic of Iran.10.1111/j.1754-9469.2008.00028.x"Iran hangs Arab separatists"Iran Overview from ArchivedConstitution of the Islamic Republic of Iran"Tehran puzzled by forged 'riots' letter""Iran and its minorities: Down in the second class""Iran: Handling Of Ahvaz Unrest Could End With Televised Confessions""Bombings Rock Iran Ahead of Election""Five die in Iran ethnic clashes""Iran: Need for restraint as anniversary of unrest in Khuzestan approaches"Archived"Iranian Sunni protesters killed in clashes with security forces"Archived