Skip to content

Commit

Permalink
Merge pull request #1 from kavehmz/init
Browse files Browse the repository at this point in the history
Init
  • Loading branch information
kavehmz committed Mar 26, 2019
2 parents dd1685a + c530fb0 commit 8a20b97
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
linters-settings:
linters:
enable:
- gosec
- golint
- misspell
- gocyclo
- gofmt
exclude-use-default: false
max-per-linter: 0
max-same-issues: 0

12 changes: 12 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
language: go
go:
- 1.x
before_install:
- go get golang.org/x/tools/cmd/cover
- go get github.com/mattn/goveralls
- go get github.com/golangci/golangci-lint/cmd/golangci-lint
script:
- go version
- go test -v -cover -coverprofile=cover.out ./...
- $HOME/gopath/bin/goveralls -coverprofile=cover.out -service=travis-ci -repotoken $COVERALLS_TOKEN
- golangci-lint run ./...
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.PHONY: $(shell ls -d *)

default:
@echo "Usage: make [command]"

test:
docker run --rm -u`id -u`:`id -g` -v $$PWD:/go/src/github.com/kavehmz/palmtree golang:1 /bin/bash -c \
cd /go/src/github.com/kavehmz/palmtree && \
go test -v --race -cover -coverprofile=cover.out ./... && \
go tool cover -func=cover.out | \
awk 'END {sub("[.].*","",$$NF); printf "Coverage: %d%%\n", $$NF; \
if ($$NF+0 < 100) {print "Coverage is not sufficient"; exit 1}}'

lint:
docker run --rm -v $$PWD:/go/src/github.com/kavehmz/palmtree -w /go/src/github.com/kavehmz/palmtree \
golangci/golangci-lint:latest golangci-lint run ./...
53 changes: 53 additions & 0 deletions palmtree.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package palmtree

import (
"sync"
)

type closer = interface {
Close() error
}

// PalmTree is a special pool for keeping closable connections
type PalmTree struct {
// Buffer sets the maximum number of connection which the pool will keep alive
// If buffer gets full new connections get closed and discarded
Buffer uint64
// A function which will generate new connections if needed
New func() closer

conns chan *closer
sync.Mutex
}

// Get will return a new connection
func (s *PalmTree) Get() closer {
s.Lock()
if s.conns == nil {
s.conns = make(chan *closer, s.Buffer)
}
s.Unlock()

var con *closer
select {
case con = <-s.conns:
default:
}

if con == nil {
return s.New()
}

return *con
}

// Put returns the connection to the pool. If pool is full it will close the connection and discard it.
// Return error is set only if Put tries to close a connection and faces any error.
func (s *PalmTree) Put(con closer) error {
select {
case s.conns <- &con:
default:
return con.Close()
}
return nil
}
63 changes: 63 additions & 0 deletions palmtree_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package palmtree_test

import (
"errors"
"testing"

"github.com/kavehmz/palmtree"
)

type mock struct{}

func (s *mock) Close() error {
return errors.New("test_closed")
}

func TestPalmTree_Get(t *testing.T) {
count := 0
p := palmtree.PalmTree{
New: func() interface{ Close() error } { // nolint: unused
count++
return &mock{}
},
Buffer: 1,
}

c1 := p.Get()
if c1 == nil || count != 1 {
t.Error("wrong result", c1, count)
}
err := p.Put(c1)
if err != nil {
t.Error("Expected no error")
}

c2 := p.Get()
if c2 == nil || count != 1 || c1 != c2 {
t.Error("wrong result. count must stay 1. c1 and c2 must be the same", c1, count)
}
err = p.Put(c2)
if err != nil {
t.Error("Expected no error")
}

c3 := p.Get()
c4 := p.Get()
if count != 2 {
t.Error("we must have 2 connections now", count, c3, c4)
}

err = p.Put(c3)
if err != nil {
t.Error("Expected to put back the connection")
}
err = p.Put(c4)
if err.Error() != "test_closed" {
t.Error("Expected to close the connection because of buffer full")
}

err = p.Get().Close()
if err.Error() != "test_closed" {
t.Error("Expected to get the same mock error ")
}
}

0 comments on commit 8a20b97

Please sign in to comment.