Showing posts with label Golang. Show all posts
Showing posts with label Golang. Show all posts

Tuesday, May 19, 2026

[Go] Concurrency Patterns - for-select loop

The for-select Loop

 golang     concurrency    for-select  

The for-select loop helps a lot in

  • Iterating something into a channel
  • Infinite loop until we tell it to stop

This example uses 2 channels, data is for sending/receiving data, done is the channel to signal the data iteration to stop in certain condition.

func IterateToChannel() {
	data := make(chan string)
	done := make(chan interface{})
	go func() {
		for v := range data {
			fmt.Print(v, " ")

			// Stop the DATA_LOOP if the value is a integer
			if _, err := strconv.Atoi(v); err == nil {
				close(done)
			}
		}
	}()

DATA_LOOP:
	for _, v := range []string{"a", "b", "1", "c"} {
		select {
		case <-done:
			break DATA_LOOP
			// return
		case data <- v:
		}
	}
}


The code prints a b 1 and stops.

Notice that in the above sample code, we can use the default case to write the incoming string to the channel data until the done channel is closed and stop the DATA_LOOP.

DATA_LOOP:
	for _, v := range []string{"a", "b", "1", "c"} {
		select {
		case <-done:
			break DATA_LOOP
        default:
            data <- v
		}
	}


Or do nothing in the default case and exit the select block.

DATA_LOOP:
	for _, v := range []string{"a", "b", "1", "c"} {
		select {
		case <-done:
			break DATA_LOOP
		default:
		}
		data <- v
	}


This example creates a infinite loop to print current time, but the loop will only run 5 times.

func InfiniteLoopThatCanStop() {
	const max int = 5
	counter := 0
	done := make(chan interface{})

LOOP:
	for {
		select {
		case <-done:
			break LOOP
		case <-time.After(1 * time.Second):
			if counter >= max {
				fmt.Println("Time's up")
				close(done)
			} else {
				// Print the current time in GMT format
				fmt.Println(time.Now().UTC().Format(http.TimeFormat))
				counter++
			}
		}
	}
}


[Go] Concurrency Patterns - Data Protected by Confinement

Data Protected by Confinement

 golang     concurrency    pattern  

Confinement ensures information is only available from one concurrent process. When this is achieved, a concurrent program is implicitly safe and no synchronization is needed.

Consider the following example.

data := []int{1, 2, 3, 4}

loopData := func(handleData chan<- int) {
	defer close(handleData)
	for _, v := range data {
		handleData <- v
	}
}

handleData := make(chan int)
go loopData(handleData)

// This line will cause deadlock
// handleData <- 5

for num := range handleData {
	fmt.Println(num)
}


If somebody adds the line handleData <- 5, the program will be deadlocked because there is another goroutine (which called loopData) was sending message to the channel handleData.

Lexical confinement can solve this problem because it uses lexical scope to expose only the correct data and concurrency primitives for multiple concurrent processes to use. It makes it impossible to do the wrong thing.

Let's update the above sample code with lexical confinemnt pattern:

data := []int{1, 2, 3, 4}

chanOwner := func() <-chan int {
	// Initiate the channel within the lexical scope of the function
	handleData := make(chan int)

	go func() {
		defer close(handleData)
		for _, v := range data {
			handleData <- v
		}
	}()
	return handleData
}

roChan := chanOwner()

for num := range roChan {
	fmt.Println(num)
}


  • The function chanOwner initiates the channel handleData in its lexical scope, and returns the readonly channel.
  • This limits the scope of write aspect of the channel to the closure that only the channel owner can write to channel, other goroutines have no chance to write but only can read from the channel.

In summary, lexical confinement has the following benefits:

  • We don't have to do the data synchorization concurrent code, because synchorization comes a cost and developer may do it wrong without any compiler error.
  • The concurrent code will be simplier to understand than without lexically confined variables and scopes.
  • Sometimes it's hard to establish confinement and we have to fall back to Go concurrency primitives.

Sunday, June 5, 2022

Friday, January 29, 2021

[Golang] Install and Get started with samples

  Golang   Get Stared    Install Golang   




 

Introduction


 

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.

See more details on golang.org.

 

Learn how to install Go, create a Hello world and some samples in the following links.


Install Go

 

1.  Install on Windows

2.  Install on Ubuntu

 

 

Hello World

 

This is the tutorial from official golang.org. 

I shorted it up in this article.



A TODO website

 

In this tutorial, we will use http package to create a TODO list website that can

  • List done and undone TODOs
  • Create new TODO
  • Remove a TODO