Git Product home page Git Product logo

Hi there πŸ‘‹,

I enjoy writing Go. Here's a fun micro-project that I did to explore what happens when you try to close a closed channel... what if I didn't want a panic to get thrown? Is it possible? Why yes it is!

safe_close.go

package main

func safeClose[T any](ch chan T) (closed bool) {
	// allow panic
	defer func() {
		if r := recover(); r != nil {
			closed = true
			return
		}
	}()
	_, chOpen := <-ch
	if chOpen {
		closed = true
		close(ch)
	} else {
		closed = false
	}
	return
}

safe_close_test.go

package main

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

func Test_safeClose(t *testing.T) {
	type args[T any] struct {
		ch chan T
	}
	type testCase[T any] struct {
		name string
		args args[T]
		want bool
	}

	// open channel with bool in buffer
	ch1 := make(chan bool, 1)
	ch1 <- true

	// closed channel with bool in buffer
	ch2 := make(chan bool, 1)
	ch2 <- false
	close(ch2)

	// closed channel with empty buffer
	ch3 := make(chan bool, 1)
	close(ch3)

	tests := []testCase[bool]{
		{
			name: "open channel with bool in buffer",
			args: args[bool]{ch1},
			want: true,
		},
		{
			name: "closed channel with bool in buffer",
			args: args[bool]{ch2},
			want: true,
		},
		{
			name: "closed channel with empty buffer",
			args: args[bool]{ch3},
			want: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			assert.Equal(t, tt.want, safeClose(tt.args.ch))
		})
	}
}

Then go run it....

go test .

Which returns:

=== RUN   Test_safeClose
--- PASS: Test_safeClose (0.00s)
=== RUN   Test_safeClose/open_channel_with_bool_in_buffer
    --- PASS: Test_safeClose/open_channel_with_bool_in_buffer (0.00s)
=== RUN   Test_safeClose/closed_channel_with_bool_in_buffer
    --- PASS: Test_safeClose/closed_channel_with_bool_in_buffer (0.00s)
=== RUN   Test_safeClose/closed_channel_with_empty_buffer
    --- PASS: Test_safeClose/closed_channel_with_empty_buffer (0.00s)
PASS

Process finished with the exit code 0

Check it out in the Go Playground...

Buy Me a Coffee at ko-fi.com

Why do I need this functionality? How does this for select statement look to you?

// wait for results
for {
	select {
	case <-ctx.Done(): // parent context canceled
		if ctx.Err() != nil {
			log.Println(ctx.Err()) // with error
		}
		closeEmAll(false)
		return ImportedAssetDownloadOutput{} // exit out of the func

	case d, chOk := <-documentResults: // documents finished!
		if chOk { // open channel
			dmu.Lock()
			documents = d                 // set documents
			documentsReceived.Store(true) // mark flag
			dmu.Unlock()
			closeAllDocuments(false)
		}

	case p, chOk := <-pageResults: // pages finished!
		if chOk { // open channel
			pmu.Lock()
			pages = p                 // set pages
			pagesReceived.Store(true) // mark flag
			pmu.Unlock()
			closeAllPages(false)
		}

	default: // when both aren't completed yet
		if documentsReceived.Load() && pagesReceived.Load() { // both received
			output := ImportedAssetDownloadOutput{ // structure the output
				ImportedDocumentsDownloadOutput: documents,
				ImportedPagesDownloadOutput:     pages,
			}

			log.Printf("total documents = %d\ntotal pages = %d\n", len(output.Documents), len(output.Pages))
			closeEmAll(true)
			return output
		}
	}
}

Andrei Merlescu's Projects

Andrei Merlescu doesn’t have any public repositories yet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.