├── .github
├── CODEOWNERS
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── dependabot.yml
└── workflows
│ ├── build.yml
│ └── release_pkg.yml
├── .gitignore
├── .go-version
├── .mergify.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── assets
└── logo.png
├── bin
└── release.sh
├── config.toml
├── go.mod
├── go.sum
├── pool.go
├── pool_test.go
├── renovate.json
├── techstack.md
└── techstack.yml
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Docs: https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
2 | * @clivern
3 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: clivern
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | **Describe the bug**
8 | A clear and concise description of what the bug is.
9 |
10 | **Development or production environment**
11 | - OS: [e.g. Ubuntu 18.04]
12 | - Go 1.13
13 |
14 | **Additional context**
15 | Add any other context about the problem here.
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 | **Is your feature request related to a problem? Please describe.**
8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9 |
10 | **Describe the solution you'd like**
11 | A clear and concise description of what you want to happen.
12 |
13 | **Additional context**
14 | Add any other context or screenshots about the feature request here.
15 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "gomod"
9 | directory: "/"
10 | schedule:
11 | interval: "daily"
12 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | pull_request:
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | strategy:
11 | fail-fast: false
12 | matrix:
13 | go: ['1.19']
14 | name: Go ${{ matrix.go }} run
15 | steps:
16 | - uses: actions/checkout@v3
17 | - name: Setup go
18 | uses: actions/setup-go@v3
19 | with:
20 | go-version: ${{ matrix.go }}
21 |
22 | - name: Get dependencies
23 | run: |
24 | export PATH=${PATH}:`go env GOPATH`/bin
25 | make install_revive
26 |
27 | - name: Run make ci
28 | run: |
29 | export PATH=${PATH}:`go env GOPATH`/bin
30 | go get -t .
31 | make ci
32 | git status
33 | git diff > diff.log
34 | cat diff.log
35 | git clean -fd
36 | git reset --hard
37 | make verify
38 |
--------------------------------------------------------------------------------
/.github/workflows/release_pkg.yml:
--------------------------------------------------------------------------------
1 | name: ReleasePkg
2 |
3 | on:
4 | push:
5 | tags:
6 | - '*'
7 |
8 | jobs:
9 | release:
10 | runs-on: ubuntu-latest
11 | steps:
12 | -
13 | name: Checkout
14 | uses: actions/checkout@v3
15 | with:
16 | fetch-depth: 0
17 | -
18 | name: Set up Go
19 | uses: actions/setup-go@v3
20 | with:
21 | go-version: 1.19
22 |
23 | - name: Update checksum database
24 | run: |
25 | ./bin/release.sh
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, build with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # dist dir
15 | dist
16 |
17 | sync
18 |
19 | *.db
20 |
21 | coverage.html
22 |
--------------------------------------------------------------------------------
/.go-version:
--------------------------------------------------------------------------------
1 | 1.19
2 |
--------------------------------------------------------------------------------
/.mergify.yml:
--------------------------------------------------------------------------------
1 | ---
2 | pull_request_rules:
3 | -
4 | actions:
5 | merge:
6 | method: squash
7 | conditions:
8 | - author!=Clivern
9 | - approved-reviews-by=Clivern
10 | - label=release
11 | name: "Automatic Merge 🚀"
12 | -
13 | actions:
14 | merge:
15 | method: merge
16 | conditions:
17 | - author=Clivern
18 | - label=release
19 | name: "Automatic Merge 🚀"
20 | -
21 | actions:
22 | merge:
23 | method: squash
24 | conditions:
25 | - "author=renovate[bot]"
26 | - label=release
27 | name: "Automatic Merge for Renovate PRs 🚀"
28 | -
29 | actions:
30 | comment:
31 | message: "Nice! PR merged successfully."
32 | conditions:
33 | - merged
34 | name: "Merge Done 🚀"
35 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at hello@clivern.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contributing
2 |
3 | - With issues:
4 | - Use the search tool before opening a new issue.
5 | - Please provide source code and commit sha if you found a bug.
6 | - Review existing issues and provide feedback or react to them.
7 |
8 | - With pull requests:
9 | - Open your pull request against `main`
10 | - Your pull request should have no more than two commits, if not you should squash them.
11 | - It should pass all tests in the available continuous integrations systems such as TravisCI.
12 | - You should add/modify tests to cover your proposed code changes.
13 | - If your pull request contains a new feature, please document it on the README.
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Clivern
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | GO ?= go
2 | GOFMT ?= $(GO)fmt
3 | pkgs = ./...
4 |
5 |
6 | help: Makefile
7 | @echo
8 | @echo " Choose a command run in Garment:"
9 | @echo
10 | @sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /'
11 | @echo
12 |
13 |
14 | ## install_revive: Install revive for linting.
15 | .PHONY: install_revive
16 | install_revive:
17 | @echo ">> ============= Install Revive ============= <<"
18 | $(GO) install github.com/mgechev/revive@latest
19 |
20 |
21 | ## style: Check code style.
22 | .PHONY: style
23 | style:
24 | @echo ">> ============= Checking Code Style ============= <<"
25 | @fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \
26 | if [ -n "$${fmtRes}" ]; then \
27 | echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \
28 | echo "Please ensure you are using $$($(GO) version) for formatting code."; \
29 | exit 1; \
30 | fi
31 |
32 |
33 | ## check_license: Check if license header on all files.
34 | .PHONY: check_license
35 | check_license:
36 | @echo ">> ============= Checking License Header ============= <<"
37 | @licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \
38 | awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \
39 | done); \
40 | if [ -n "$${licRes}" ]; then \
41 | echo "license header checking failed:"; echo "$${licRes}"; \
42 | exit 1; \
43 | fi
44 |
45 |
46 | ## test_short: Run test cases with short flag.
47 | .PHONY: test_short
48 | test_short:
49 | @echo ">> ============= Running Short Tests ============= <<"
50 | $(GO) clean -testcache
51 | $(GO) test -mod=readonly -short $(pkgs)
52 |
53 |
54 | ## test: Run test cases.
55 | .PHONY: test
56 | test:
57 | @echo ">> ============= Running All Tests ============= <<"
58 | $(GO) clean -testcache
59 | $(GO) test -mod=readonly -run=Unit -bench=. -benchmem -v -cover $(pkgs)
60 |
61 |
62 | ## lint: Lint the code.
63 | .PHONY: lint
64 | lint:
65 | @echo ">> ============= Lint All Files ============= <<"
66 | revive -config config.toml -exclude vendor/... -formatter friendly ./...
67 |
68 |
69 | ## verify: Verify dependencies
70 | .PHONY: verify
71 | verify:
72 | @echo ">> ============= List Dependencies ============= <<"
73 | $(GO) list -m all
74 | @echo ">> ============= Verify Dependencies ============= <<"
75 | $(GO) mod verify
76 |
77 |
78 | ## format: Format the code.
79 | .PHONY: format
80 | format:
81 | @echo ">> ============= Formatting Code ============= <<"
82 | $(GO) fmt $(pkgs)
83 |
84 |
85 | ## vet: Examines source code and reports suspicious constructs.
86 | .PHONY: vet
87 | vet:
88 | @echo ">> ============= Vetting Code ============= <<"
89 | $(GO) vet $(pkgs)
90 |
91 |
92 | ## coverage: Create HTML coverage report
93 | .PHONY: coverage
94 | coverage:
95 | @echo ">> ============= Coverage ============= <<"
96 | rm -f coverage.html cover.out
97 | $(GO) test -mod=readonly -coverprofile=cover.out $(pkgs)
98 | go tool cover -html=cover.out -o coverage.html
99 |
100 |
101 | ## ci: Run all CI tests.
102 | .PHONY: ci
103 | ci: style check_license test vet lint
104 | @echo "\n==> All quality checks passed"
105 |
106 |
107 | .PHONY: help
108 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Garment
4 | A Thread Safe Connection Pooling.
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Garment retains a single connection pool for different database types used inside you application (MySQL, Redis, Etcd ... etc). Please note that garment won't be needed and not recommended if you already preserve the same connection pool across your application sub packages.
25 |
26 |
27 | ## Documentation
28 |
29 | #### Usage
30 |
31 | Install the package with:
32 |
33 | ```zsh
34 | $ go get github.com/norwik/garment
35 | ```
36 |
37 | Here is an example:
38 |
39 | ```golang
40 | package main
41 |
42 | import (
43 | "errors"
44 | "fmt"
45 |
46 | "github.com/norwik/garment"
47 | )
48 |
49 | type Database struct {
50 | State string
51 | }
52 |
53 | func (d *Database) GetState() string {
54 | return d.State
55 | }
56 |
57 | func (d *Database) Terminate() {
58 | d.State = "disconnected"
59 | }
60 |
61 | func (d *Database) Close() {
62 | d.State = "disconnected"
63 | }
64 |
65 | func (d *Database) Reconnect() {
66 | d.State = "connected"
67 | }
68 |
69 | func (d *Database) Ping() bool {
70 | if d.State == "connected" {
71 | return true
72 | }
73 |
74 | return false
75 | }
76 |
77 | func main() {
78 | pool := garment.NewPool()
79 |
80 | ping := func(con interface{}) error {
81 | if con.(*Database).Ping() {
82 | return nil
83 | }
84 |
85 | return errors.New("DB connection is lost")
86 | }
87 |
88 | close := func(con interface{}) error {
89 | con.(*Database).Close()
90 |
91 | return nil
92 | }
93 |
94 | reconnect := func(con interface{}) error {
95 | con.(*Database).Reconnect()
96 |
97 | return nil
98 | }
99 |
100 | pool.Set("db", &Database{State: "connected"}, ping, close, reconnect)
101 |
102 | fmt.Println(pool.Count()) // 1
103 |
104 | fmt.Println(pool.Has("db")) // true
105 | fmt.Println(pool.Ping("db")) //
106 |
107 | fmt.Println(pool.Get("db").(*Database).GetState()) // connected
108 |
109 | pool.Close("db")
110 |
111 | fmt.Println(pool.Get("db").(*Database).GetState()) // disconnected
112 |
113 | pool.Reconnect("db")
114 |
115 | fmt.Println(pool.Get("db").(*Database).GetState()) // connected
116 |
117 | pool.Get("db").(*Database).Terminate()
118 |
119 | fmt.Println(pool.Get("db").(*Database).GetState()) // disconnected
120 |
121 | pool.Remove("db")
122 |
123 | fmt.Println(pool.Count()) // 0
124 | }
125 | ```
126 |
127 | ## Versioning
128 |
129 | For transparency into our release cycle and in striving to maintain backward compatibility, Garment is maintained under the [Semantic Versioning guidelines](https://semver.org/) and release process is predictable and business-friendly.
130 |
131 | See the [Releases section of our GitHub project](https://github.com/norwik/garment/releases) for changelogs for each release version of Garment. It contains summaries of the most noteworthy changes made in each release.
132 |
133 |
134 | ## Bug tracker
135 |
136 | If you have any suggestions, bug reports, or annoyances please report them to our issue tracker at https://github.com/norwik/garment/issues
137 |
138 |
139 | ## Security Issues
140 |
141 | If you discover a security vulnerability within Garment, please send an email to [hello@clivern.com](mailto:hello@clivern.com)
142 |
143 |
144 | ## Contributing
145 |
146 | We are an open source, community-driven project so please feel free to join us. see the [contributing guidelines](CONTRIBUTING.md) for more details.
147 |
148 |
149 | ## License
150 |
151 | © 2021, Clivern. Released under [MIT License](https://opensource.org/licenses/mit-license.php).
152 |
153 | **Garment** is authored and maintained by [@Clivern](http://github.com/Clivern).
154 |
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Norwik/Garment/106385d746876183f218427d5becc947dd9b110d/assets/logo.png
--------------------------------------------------------------------------------
/bin/release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Fetch latest version
4 | export LATEST_VERSION=$(curl --silent "https://api.github.com/repos/norwik/garment/releases/latest" | jq '.tag_name' | sed -E 's/.*"([^"]+)".*/\1/')
5 |
6 | # Update go checksum database (sum.golang.org) immediately after release
7 | curl --silent https://sum.golang.org/lookup/github.com/norwik/garment@{$LATEST_VERSION}
8 |
--------------------------------------------------------------------------------
/config.toml:
--------------------------------------------------------------------------------
1 | ignoreGeneratedHeader = false
2 | severity = "warning"
3 | confidence = 0.8
4 | errorCode = 0
5 | warningCode = 0
6 |
7 | [rule.blank-imports]
8 | [rule.context-as-argument]
9 | [rule.context-keys-type]
10 | [rule.dot-imports]
11 | [rule.error-return]
12 | [rule.error-strings]
13 | [rule.error-naming]
14 | [rule.exported]
15 | [rule.if-return]
16 | [rule.increment-decrement]
17 | [rule.var-naming]
18 | [rule.var-declaration]
19 | [rule.package-comments]
20 | [rule.range]
21 | [rule.receiver-naming]
22 | [rule.time-naming]
23 | [rule.unexported-return]
24 | [rule.indent-error-flow]
25 | [rule.errorf]
26 | [rule.empty-block]
27 | [rule.superfluous-else]
28 | [rule.unused-parameter]
29 | [rule.unreachable-code]
30 | [rule.redefines-builtin-id]
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/norwik/garment
2 |
3 | go 1.19
4 |
5 | require github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf
6 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf h1:NrF81UtW8gG2LBGkXFQFqlfNnvMt9WdB46sfdJY4oqc=
2 | github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo=
3 |
--------------------------------------------------------------------------------
/pool.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Clivern. All rights reserved.
2 | // Use of this source code is governed by the MIT
3 | // license that can be found in the LICENSE file.
4 |
5 | package garment
6 |
7 | import (
8 | "fmt"
9 | "sync"
10 | )
11 |
12 | var (
13 | // pool var
14 | pool *Pool
15 | // once var
16 | once sync.Once
17 | )
18 |
19 | // PingCallback type
20 | type PingCallback func(interface{}) error
21 |
22 | // CloseCallback type
23 | type CloseCallback func(interface{}) error
24 |
25 | // ReconnectCallback type
26 | type ReconnectCallback func(interface{}) error
27 |
28 | // Connection type
29 | type Connection struct {
30 | Value interface{}
31 | Ping PingCallback
32 | Close CloseCallback
33 | Reconnect ReconnectCallback
34 | }
35 |
36 | // Pool type
37 | type Pool struct {
38 | sync.RWMutex
39 |
40 | items map[string]Connection
41 | }
42 |
43 | // NewPool creates a new instance of Pool
44 | func NewPool() *Pool {
45 | once.Do(func() {
46 | pool = &Pool{
47 | items: make(map[string]Connection),
48 | }
49 | })
50 |
51 | return pool
52 | }
53 |
54 | // Get gets a connection with a key
55 | func (c *Pool) Get(key string) interface{} {
56 | c.Lock()
57 | defer c.Unlock()
58 |
59 | connection, ok := c.items[key]
60 |
61 | if !ok {
62 | return nil
63 | }
64 |
65 | return connection.Value
66 | }
67 |
68 | // Has checks if connection exists
69 | func (c *Pool) Has(key string) bool {
70 | if val := c.Get(key); val != nil {
71 | return true
72 | }
73 |
74 | return false
75 | }
76 |
77 | // Set sets a connection with a key
78 | func (c *Pool) Set(key string, value interface{}, ping PingCallback, close CloseCallback, reconnect ReconnectCallback) {
79 | c.Lock()
80 | defer c.Unlock()
81 |
82 | c.items[key] = Connection{
83 | Value: value,
84 | Ping: ping,
85 | Close: close,
86 | Reconnect: reconnect,
87 | }
88 | }
89 |
90 | // Close close the connection and removes the key
91 | func (c *Pool) Close(key string) error {
92 | c.Lock()
93 | defer c.Unlock()
94 |
95 | connection, ok := c.items[key]
96 |
97 | if !ok {
98 | return fmt.Errorf("Unable to find %s", key)
99 | }
100 |
101 | return connection.Close(connection.Value)
102 | }
103 |
104 | // Ping checks the connection status
105 | func (c *Pool) Ping(key string) error {
106 | c.Lock()
107 | defer c.Unlock()
108 |
109 | connection, ok := c.items[key]
110 |
111 | if !ok {
112 | return fmt.Errorf("Unable to find %s", key)
113 | }
114 |
115 | return connection.Ping(connection.Value)
116 | }
117 |
118 | // Reconnect reconnects again
119 | func (c *Pool) Reconnect(key string) error {
120 | c.Lock()
121 | defer c.Unlock()
122 |
123 | connection, ok := c.items[key]
124 |
125 | if !ok {
126 | return fmt.Errorf("Unable to find %s", key)
127 | }
128 |
129 | return connection.Reconnect(connection.Value)
130 | }
131 |
132 | // Remove removes a connection
133 | func (c *Pool) Remove(key string) {
134 | c.Lock()
135 | defer c.Unlock()
136 |
137 | _, ok := c.items[key]
138 |
139 | if !ok {
140 | return
141 | }
142 |
143 | delete(c.items, key)
144 | }
145 |
146 | // Count counts the number of managed connections
147 | func (c *Pool) Count() int {
148 | c.Lock()
149 | defer c.Unlock()
150 |
151 | return len(c.items)
152 | }
153 |
--------------------------------------------------------------------------------
/pool_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Clivern. All rights reserved.
2 | // Use of this source code is governed by the MIT
3 | // license that can be found in the LICENSE file.
4 |
5 | package garment
6 |
7 | import (
8 | "errors"
9 | "testing"
10 |
11 | "github.com/franela/goblin"
12 | )
13 |
14 | type DatabaseClient struct {
15 | Connection int
16 | }
17 |
18 | func (d *DatabaseClient) Execute() int {
19 | return d.Connection
20 | }
21 |
22 | func (d *DatabaseClient) Terminate() {
23 | d.Connection = 0
24 | }
25 |
26 | func (d *DatabaseClient) Close() {
27 | d.Connection = 0
28 | }
29 |
30 | func (d *DatabaseClient) Reconnect() {
31 | d.Connection = 1
32 | }
33 |
34 | func (d *DatabaseClient) Ping() bool {
35 | if d.Connection == 1 {
36 | return true
37 | }
38 |
39 | return false
40 | }
41 |
42 | // TestUnitPool test cases
43 | func TestUnitPool(t *testing.T) {
44 | g := goblin.Goblin(t)
45 |
46 | g.Describe("#Pool", func() {
47 | g.It("It should satisfy all provided test cases", func() {
48 | pool1 := NewPool()
49 | pool2 := NewPool()
50 |
51 | g.Assert(pool1.Count()).Equal(0)
52 | g.Assert(pool2.Count()).Equal(0)
53 |
54 | ping := func(con interface{}) error {
55 | if con.(*DatabaseClient).Ping() {
56 | return nil
57 | }
58 |
59 | return errors.New("DB connection is lost")
60 | }
61 |
62 | close := func(con interface{}) error {
63 | con.(*DatabaseClient).Close()
64 |
65 | return nil
66 | }
67 |
68 | reconnect := func(con interface{}) error {
69 | con.(*DatabaseClient).Reconnect()
70 |
71 | return nil
72 | }
73 |
74 | pool1.Set("db", &DatabaseClient{Connection: 1}, ping, close, reconnect)
75 |
76 | // Concurrent Access
77 | go func() {
78 | for i := 0; i < 100; i++ {
79 | if pool1.Has("db") && pool1.Ping("db") == nil {
80 | g.Assert(pool1.Get("db").(*DatabaseClient).Execute()).Equal(1)
81 | }
82 | }
83 | }()
84 |
85 | go func() {
86 | for i := 0; i < 100; i++ {
87 | if pool1.Has("db") && pool1.Ping("db") == nil {
88 | g.Assert(pool1.Get("db").(*DatabaseClient).Execute()).Equal(1)
89 | }
90 | }
91 | }()
92 |
93 | g.Assert(pool1.Count()).Equal(1)
94 | g.Assert(pool2.Count()).Equal(1)
95 |
96 | g.Assert(pool1.Has("db")).Equal(true)
97 | g.Assert(pool2.Has("db")).Equal(true)
98 |
99 | g.Assert(pool1.Has("db1")).Equal(false)
100 | g.Assert(pool2.Has("db1")).Equal(false)
101 |
102 | g.Assert(pool1.Get("db").(*DatabaseClient).Execute()).Equal(1)
103 | g.Assert(pool2.Get("db").(*DatabaseClient).Execute()).Equal(1)
104 |
105 | // Terminate Connection
106 | pool2.Get("db").(*DatabaseClient).Terminate()
107 | g.Assert(pool1.Get("db").(*DatabaseClient).Execute()).Equal(0)
108 | pool1.Reconnect("db")
109 | g.Assert(pool1.Get("db").(*DatabaseClient).Execute()).Equal(1)
110 | pool2.Remove("db")
111 | pool1.Reconnect("db")
112 | pool2.Remove("db")
113 | pool2.Ping("db")
114 |
115 | g.Assert(pool1.Has("db")).Equal(false)
116 | g.Assert(pool2.Has("db")).Equal(false)
117 |
118 | g.Assert(pool1.Count()).Equal(0)
119 | g.Assert(pool2.Count()).Equal(0)
120 |
121 | pool2.Set("db", &DatabaseClient{Connection: 1}, ping, close, reconnect)
122 |
123 | g.Assert(pool1.Count()).Equal(1)
124 | g.Assert(pool2.Count()).Equal(1)
125 |
126 | g.Assert(pool1.Ping("db") == nil).Equal(true)
127 | g.Assert(pool2.Ping("db") == nil).Equal(true)
128 |
129 | pool1.Close("db")
130 | pool1.Close("db1")
131 |
132 | g.Assert(pool1.Ping("db") == nil).Equal(false)
133 | g.Assert(pool2.Ping("db") == nil).Equal(false)
134 |
135 | g.Assert(pool1.Count()).Equal(1)
136 | g.Assert(pool2.Count()).Equal(1)
137 | })
138 | })
139 | }
140 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/techstack.md:
--------------------------------------------------------------------------------
1 |
26 |
27 |
28 | # Tech Stack File
29 |  [Norwik/Garment](https://github.com/Norwik/Garment)
30 |
31 | |5
Tools used|12/21/23
Report generated|
32 | |------|------|
33 |
34 |
35 | ##
Languages (1)
36 |
37 |
38 |
39 |
40 | Golang
41 |
42 |
43 | |
44 |
45 |
46 |
47 |
48 | ##
DevOps (2)
49 |
50 |
51 |
52 |
53 | Git
54 |
55 |
56 | |
57 |
58 |
59 |
60 |
61 | GitHub Actions
62 |
63 |
64 | |
65 |
66 |
67 |
68 |
69 | ## Other (1)
70 |
71 |
72 |
73 |
74 | Shell
75 |
76 |
77 | |
78 |
79 |
80 |
81 |
82 |
83 | ##
Open source packages (1)
84 |
85 | ##
Go Packages (1)
86 |
87 | |NAME|VERSION|LAST UPDATED|LAST UPDATED BY|LICENSE|VULNERABILITIES|
88 | |:------|:------|:------|:------|:------|:------|
89 | |[goblin](https://pkg.go.dev/github.com/franela/goblin)|v0.0.0|06/26/22|renovate[bot] |MIT|N/A|
90 |
91 |
92 |
93 |
94 | Generated via [Stack File](https://github.com/marketplace/stack-file)
95 |
--------------------------------------------------------------------------------
/techstack.yml:
--------------------------------------------------------------------------------
1 | repo_name: Norwik/Garment
2 | report_id: f5293acf9ae60108ce94c074d9dc07e4
3 | version: 0.1
4 | repo_type: Public
5 | timestamp: '2023-12-21T15:24:24+00:00'
6 | requested_by: Clivern
7 | provider: github
8 | branch: main
9 | detected_tools_count: 5
10 | tools:
11 | - name: Golang
12 | description: An open source programming language that makes it easy to build simple,
13 | reliable, and efficient software
14 | website_url: http://golang.org/
15 | license: BSD-3-Clause
16 | open_source: true
17 | hosted_saas: false
18 | category: Languages & Frameworks
19 | sub_category: Languages
20 | image_url: https://img.stackshare.io/service/1005/O6AczwfV_400x400.png
21 | detection_source: Repo Metadata
22 | - name: Git
23 | description: Fast, scalable, distributed revision control system
24 | website_url: http://git-scm.com/
25 | open_source: true
26 | hosted_saas: false
27 | category: Build, Test, Deploy
28 | sub_category: Version Control System
29 | image_url: https://img.stackshare.io/service/1046/git.png
30 | detection_source: Repo Metadata
31 | - name: GitHub Actions
32 | description: Automate your workflow from idea to production
33 | website_url: https://github.com/features/actions
34 | open_source: false
35 | hosted_saas: true
36 | category: Build, Test, Deploy
37 | sub_category: Continuous Integration
38 | image_url: https://img.stackshare.io/service/11563/actions.png
39 | detection_source: ".github/workflows/build.yml"
40 | last_updated_by: renovate[bot]
41 | last_updated_on: 2022-06-27 11:13:39.000000000 Z
42 | - name: Shell
43 | description: A shell is a text-based terminal, used for manipulating programs and
44 | files. Shell scripts typically manage program execution.
45 | website_url: https://en.wikipedia.org/wiki/Shell_script
46 | open_source: false
47 | hosted_saas: false
48 | category: Languages & Frameworks
49 | sub_category: Languages
50 | image_url: https://img.stackshare.io/service/4631/default_c2062d40130562bdc836c13dbca02d318205a962.png
51 | detection_source: Repo Metadata
52 | - name: goblin
53 | description: Minimal and Beautiful Go testing framework
54 | package_url: https://pkg.go.dev/github.com/franela/goblin
55 | version: 0.0.0
56 | license: MIT
57 | open_source: true
58 | hosted_saas: false
59 | category: Libraries
60 | sub_category: Go Modules Packages
61 | image_url: https://img.stackshare.io/package/go-packages/image.png
62 | detection_source_url: https://github.com/Norwik/Garment/blob/main/go.sum
63 | detection_source: go.mod
64 | last_updated_by: renovate[bot]
65 | last_updated_on: 2022-06-26 22:36:44.000000000 Z
66 |
--------------------------------------------------------------------------------