Git with a cup of tea! Painless self-hosted all-in-one software development service, includes Git hosting, code review, team collaboration, package registry and CI/CD
Go to file
Jason Song bc0977f1c9
Refactor globallock (#31933)
Follow #31908. The main refactor is that it has removed the returned
context of `Lock`.

The returned context of `Lock` in old code is to provide a way to let
callers know that they have lost the lock. But in most cases, callers
shouldn't cancel what they are doing even it has lost the lock. And the
design would confuse developers and make them use it incorrectly.

See the discussion history:
https://github.com/go-gitea/gitea/pull/31813#discussion_r1732041513 and
https://github.com/go-gitea/gitea/pull/31813#discussion_r1734078998

It's a breaking change, but since the new module hasn't been used yet, I
think it's OK to not add the `pr/breaking` label.

## Design principles

It's almost copied from #31908, but with some changes.

### Use spinlock even in memory implementation (unchanged)

In actual use cases, users may cancel requests. `sync.Mutex` will block
the goroutine until the lock is acquired even if the request is
canceled. And the spinlock is more suitable for this scenario since it's
possible to give up the lock acquisition.

Although the spinlock consumes more CPU resources, I think it's
acceptable in most cases.

### Do not expose the mutex to callers (unchanged)

If we expose the mutex to callers, it's possible for callers to reuse
the mutex, which causes more complexity.

For example:
```go
lock := GetLocker(key)
lock.Lock()
// ...
// even if the lock is unlocked, we cannot GC the lock,
// since the caller may still use it again.
lock.Unlock()
lock.Lock()
// ...
lock.Unlock()

// callers have to GC the lock manually.
RemoveLocker(key)
```

That's why
https://github.com/go-gitea/gitea/pull/31813#discussion_r1721200549

In this PR, we only expose `ReleaseFunc` to callers. So callers just
need to call `ReleaseFunc` to release the lock, and do not need to care
about the lock's lifecycle.
```go
release, err := locker.Lock(ctx, key)
if err != nil {
    return err
}
// ...
release()

// if callers want to lock again, they have to re-acquire the lock.
release, err := locker.Lock(ctx, key)
// ...
```

In this way, it's also much easier for redis implementation to extend
the mutex automatically, so that callers do not need to care about the
lock's lifecycle. See also
https://github.com/go-gitea/gitea/pull/31813#discussion_r1722659743

### Use "release" instead of "unlock" (unchanged)

For "unlock", it has the meaning of "unlock an acquired lock". So it's
not acceptable to call "unlock" when failed to acquire the lock, or call
"unlock" multiple times. It causes more complexity for callers to decide
whether to call "unlock" or not.

So we use "release" instead of "unlock" to make it clear. Whether the
lock is acquired or not, callers can always call "release", and it's
also safe to call "release" multiple times.

But the code DO NOT expect callers to not call "release" after acquiring
the lock. If callers forget to call "release", it will cause resource
leak. That's why it's always safe to call "release" without extra
checks: to avoid callers to forget to call it.

### Acquired locks could be lost, but the callers shouldn't stop

Unlike `sync.Mutex` which will be locked forever once acquired until
calling `Unlock`, for distributed lock, the acquired lock could be lost.

For example, the caller has acquired the lock, and it holds the lock for
a long time since auto-extending is working for redis. However, it lost
the connection to the redis server, and it's impossible to extend the
lock anymore.

In #31908, it will cancel the context to make the operation stop, but
it's not safe. Many operations are not revert-able. If they have been
interrupted, then the instance goes corrupted. So `Lock` won't return
`ctx` anymore in this PR.

### Multiple ways to use the lock

1. Regular way

```go
release, err := Lock(ctx, key)
if err != nil {
    return err
}
defer release()
// ...
```

2. Early release

```go
release, err := Lock(ctx, key)
if err != nil {
    return err
}
defer release()
// ...
// release the lock earlier
release()
// continue to do something else
// ...
```

3. Functional way

```go
if err := LockAndDo(ctx, key, func(ctx context.Context) error {
    // ...
    return nil
}); err != nil {
    return err
}
```
2024-08-29 03:48:21 +00:00
.devcontainer Remove sqlite-viewer and using database client (#31223) 2024-06-03 10:41:29 +00:00
.gitea Update demo site location from try.gitea.io -> demo.gitea.com (#31054) 2024-05-27 15:05:12 +00:00
.github Add label `docs-update-needed` for PRs that modify `app.example.ini` (#31810) 2024-08-10 00:20:59 +08:00
assets Support compression for Actions logs (#31761) 2024-08-09 10:10:30 +08:00
build Add `interface{}` to `any` replacement to `make fmt`, exclude `*.pb.go` (#30461) 2024-04-13 17:32:15 +00:00
cmd fix: allow actions artifacts storage migration to complete succesfully (#31251) 2024-06-05 12:00:56 +08:00
contrib Bump `github.com/google/go-github` to v61 (#30738) 2024-04-28 01:20:23 -04:00
custom/conf Fix typo for `LOG_COMPRESSION` in ini (#31809) 2024-08-10 06:07:35 +08:00
docker Update README.md (#30856) 2024-05-03 23:53:18 -04:00
models Remove "dsa-1024" testcases from Test_SSHParsePublicKey and Test_calcFingerprint (#31905) 2024-08-24 10:07:16 +00:00
modules Refactor globallock (#31933) 2024-08-29 03:48:21 +00:00
options [skip ci] Updated translations via Crowdin 2024-08-27 00:28:30 +00:00
public Update JS dependencies (#31616) 2024-07-11 14:36:02 -04:00
routers Split org Propfile README to a new tab `overview` (#31373) 2024-08-27 10:54:12 +08:00
services Handle "close" actionable references for manual merges (#31879) 2024-08-26 01:18:19 +08:00
snap bump to use go 1.22 (#29119) 2024-02-14 18:19:57 +00:00
templates Split org Propfile README to a new tab `overview` (#31373) 2024-08-27 10:54:12 +08:00
tests Fix agit automerge (#31207) 2024-08-20 14:17:21 +08:00
tools Add `lint-go-gopls` (#30729) 2024-06-05 09:22:38 +08:00
web_src Fix a number of Typescript issues (#31877) 2024-08-28 18:32:38 +02:00
.air.toml Reduce `air` verbosity (#31417) 2024-06-19 19:42:06 +00:00
.changelog.yml Adapt `.changelog.yml` to new labeling system (#27701) 2023-10-20 00:22:00 +02:00
.dockerignore Add `/public/assets/img/webpack` to ignore files again (#30451) 2024-04-13 04:28:20 +02:00
.editorconfig Add markdownlint (#20512) 2022-07-28 09:22:47 +08:00
.envrc Enable direnv (#31672) 2024-07-23 12:07:41 +00:00
.eslintrc.yaml Update JS dependencies (#31766) 2024-08-02 21:28:12 +00:00
.gitattributes Add `interface{}` to `any` replacement to `make fmt`, exclude `*.pb.go` (#30461) 2024-04-13 17:32:15 +00:00
.gitignore Enable direnv (#31672) 2024-07-23 12:07:41 +00:00
.gitpod.yml Remove sqlite-viewer and using database client (#31223) 2024-06-03 10:41:29 +00:00
.golangci.yml Enable `unparam` linter (#31277) 2024-06-11 18:47:45 +00:00
.ignore Add `/options/license` and `/options/gitignore` to `.ignore` (#30219) 2024-03-31 22:22:29 +02:00
.markdownlint.yaml Enable markdownlint `no-trailing-punctuation` and `no-blanks-blockquote` (#29214) 2024-02-17 13:18:05 +00:00
.npmrc Upgrade to npm lockfile v3 and explicitely set it (#23561) 2023-03-18 19:38:10 +01:00
.spectral.yaml Add spectral linter for Swagger (#20321) 2022-07-11 18:07:16 -05:00
.yamllint.yaml fully replace drone with actions (#27556) 2023-10-11 06:39:32 +00:00
BSDmakefile Fix build errors on BSD (in BSDMakefile) (#27594) 2023-10-13 15:38:27 +00:00
CHANGELOG-archived.md Fix changelog (main) (#30582) 2024-04-19 06:08:30 +00:00
CHANGELOG.md Fix changelog (main) (#30582) 2024-04-19 06:08:30 +00:00
CODE_OF_CONDUCT.md Add Gitea Community Code of Conduct (#23188) 2023-03-09 10:49:34 +08:00
CONTRIBUTING.md Have new announcement about docs contributions (#31364) 2024-06-14 11:17:05 +08:00
DCO Remove address from DCO (#22595) 2023-01-24 18:52:38 +00:00
Dockerfile Fix deprecated Dockerfile ENV format (#31450) 2024-06-21 11:08:42 -04:00
Dockerfile.rootless Fix deprecated Dockerfile ENV format (#31450) 2024-06-21 11:08:42 -04:00
LICENSE Fix typo 2016-11-08 08:42:05 +01:00
MAINTAINERS Add bohde as maintainer (#31601) 2024-07-10 08:18:35 +08:00
Makefile Add `TAGS` to `TEST_TAGS` and fix bugs found with gogit (#31791) 2024-08-07 11:29:08 -04:00
README.md README Badge maintenance (#31441) 2024-06-21 13:18:39 +00:00
README_ZH.md README Badge maintenance (#31441) 2024-06-21 13:18:39 +00:00
SECURITY.md typo on date in security document (#31617) 2024-07-11 21:51:08 +00:00
build.go User/Org Feed render description as per web (#23887) 2023-04-04 04:39:47 +01:00
crowdin.yml Use Crowdin action for translation sync (#30054) 2024-03-30 18:11:50 +00:00
flake.lock Fix update flake (#31626) 2024-07-12 16:25:54 +00:00
flake.nix Fix update flake (#31626) 2024-07-12 16:25:54 +00:00
go.mod Introduce globallock as distributed locks (#31908) 2024-08-26 22:27:57 +08:00
go.sum Introduce globallock as distributed locks (#31908) 2024-08-26 22:27:57 +08:00
main.go Add some tests to clarify the "must-change-password" behavior (#30693) 2024-04-27 12:23:37 +00:00
package-lock.json Update mermaid to v11 (#31913) 2024-08-25 17:23:13 +00:00
package.json Update mermaid to v11 (#31913) 2024-08-25 17:23:13 +00:00
playwright.config.ts Add initial typescript config and use it for eslint,vitest,playwright (#31186) 2024-06-28 16:15:51 +00:00
poetry.lock Upgrade `tqdm` dependency (#30996) 2024-05-16 19:40:57 +00:00
poetry.toml Clean up pyproject.toml and package.json, fix poetry options (#25327) 2023-06-18 18:13:08 +00:00
pyproject.toml Enable poetry non-package mode (#31282) 2024-06-07 15:37:33 +02:00
stylelint.config.js Enable `declaration-block-no-redundant-longhand-properties` (#30950) 2024-05-12 02:33:05 +00:00
tailwind.config.js Add spacing to global error message (#31826) 2024-08-14 01:58:26 +00:00
tsconfig.json Convert frontend code to typescript (#31559) 2024-07-07 15:32:30 +00:00
types.d.ts Fix a number of Typescript issues (#31877) 2024-08-28 18:32:38 +02:00
updates.config.js Update JS dependencies (#31120) 2024-05-28 01:50:28 +00:00
vitest.config.ts Convert frontend code to typescript (#31559) 2024-07-07 15:32:30 +00:00
webpack.config.js Add back esbuild-loader for .js files (#31585) 2024-07-09 09:28:43 +00:00

README.md

Gitea

Contribute with Gitpod

View this document in Chinese

Purpose

The goal of this project is to make the easiest, fastest, and most painless way of setting up a self-hosted Git service.

As Gitea is written in Go, it works across all the platforms and architectures that are supported by Go, including Linux, macOS, and Windows on x86, amd64, ARM and PowerPC architectures. This project has been forked from Gogs since November of 2016, but a lot has changed.

For online demonstrations, you can visit demo.gitea.com.

For accessing free Gitea service (with a limited number of repositories), you can visit gitea.com.

To quickly deploy your own dedicated Gitea instance on Gitea Cloud, you can start a free trial at cloud.gitea.com.

Building

From the root of the source tree, run:

TAGS="bindata" make build

or if SQLite support is required:

TAGS="bindata sqlite sqlite_unlock_notify" make build

The build target is split into two sub-targets:

  • make backend which requires Go Stable, the required version is defined in go.mod.
  • make frontend which requires Node.js LTS or greater.

Internet connectivity is required to download the go and npm modules. When building from the official source tarballs which include pre-built frontend files, the frontend target will not be triggered, making it possible to build without Node.js.

More info: https://docs.gitea.com/installation/install-from-source

Using

./gitea web

[!NOTE] If you're interested in using our APIs, we have experimental support with documentation.

Contributing

Expected workflow is: Fork -> Patch -> Push -> Pull Request

[!NOTE]

  1. YOU MUST READ THE CONTRIBUTORS GUIDE BEFORE STARTING TO WORK ON A PULL REQUEST.
  2. If you have found a vulnerability in the project, please write privately to security@gitea.io. Thanks!

Translating

Translations are done through Crowdin. If you want to translate to a new language ask one of the managers in the Crowdin project to add a new language there.

You can also just create an issue for adding a language or ask on discord on the #translation channel. If you need context or find some translation issues, you can leave a comment on the string or ask on Discord. For general translation questions there is a section in the docs. Currently a bit empty but we hope to fill it as questions pop up.

https://docs.gitea.com/contributing/localization

Crowdin

Further information

For more information and instructions about how to install Gitea, please look at our documentation. If you have questions that are not covered by the documentation, you can get in contact with us on our Discord server or create a post in the discourse forum.

We maintain a list of Gitea-related projects at gitea/awesome-gitea.

The official Gitea CLI is developed at gitea/tea.

Authors

Backers

Thank you to all our backers! 🙏 [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

FAQ

How do you pronounce Gitea?

Gitea is pronounced /ɡɪti:/ as in "gi-tea" with a hard g.

Why is this not hosted on a Gitea instance?

We're working on it.

License

This project is licensed under the MIT License. See the LICENSE file for the full license text.

Screenshots

Looking for an overview of the interface? Check it out!

Dashboard User Profile Global Issues
Branches Web Editor Activity
New Migration Migrating Pull Request View
Pull Request Dark Diff Review Dark Diff Dark