Skip to content

Commit

Permalink
Add godocs for github.com/samuong/alpaca/cancelable
Browse files Browse the repository at this point in the history
  • Loading branch information
samuong committed Oct 2, 2020
1 parent f3cfc38 commit 25fd9e1
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
12 changes: 11 additions & 1 deletion cancelable/closer.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019 The Alpaca Authors
// Copyright 2019, 2020 The Alpaca Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -12,24 +12,34 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package cancelable provides a cancelable version of io.Closer.
//
// This is intended to be used by functions where the responsibility for closing
// a resource sometimes belongs to the function itself (e.g. early returns due
// to error handling), and sometimes belongs to the caller.
package cancelable

import (
"io"
)

// Closer is an io.Closer that can be cancelled.
type Closer struct {
c io.Closer
}

// NewCloser returns a cancelable.Closer that wraps an io.Closer.
func NewCloser(c io.Closer) *Closer {
return &Closer{c: c}
}

// Cancel turns any future calls to Close into a no-op.
func (c *Closer) Cancel() {
c.c = nil
}

// Close calls the Close function on the io.Closer (if it has not been cancelled
// or already closed). It is safe to call this multiple times.
func (c *Closer) Close() error {
if c.c == nil {
return nil
Expand Down
58 changes: 58 additions & 0 deletions cancelable/example_closer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2020 The Alpaca Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cancelable_test

import (
"fmt"

"github.com/samuong/alpaca/cancelable"
)

type printCloser struct {
msg string
}

// Close prints the printCloser's msg on stdout.
func (pc *printCloser) Close() error {
fmt.Printf("Close() called: %s\n", pc.msg)
return nil
}

func ExampleCloser() {
c := create(false) // defer in create() prints once
c.Close() // prints again

c = create(true) // defer cancelled, no print
c.Close() // prints

// Output:
// Close() called: doCancel: false
// Close() called: doCancel: false
// Close() called: doCancel: true
}

func create(doCancel bool) *printCloser {
pc := &printCloser{fmt.Sprintf("doCancel: %v", doCancel)}

closer := cancelable.NewCloser(pc)
defer closer.Close()

if !doCancel {
return pc // deferred Close will cause msg to be printed
}

closer.Cancel() // Cancel will prevent Close being called from defer
return pc
}

0 comments on commit 25fd9e1

Please sign in to comment.