mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-06 23:16:52 +02:00
Use global lock instead of NewExclusivePool to allow distributed lock between multiple Gitea instances (#31813)
Replace #26486 Fix #19620 --------- Co-authored-by: Jason Song <i@wolfogre.com>
This commit is contained in:
1 parent
a5818470fe
commit
2da2000413
13 files changed
+185
-107
No files matched your search
Generated
+15
@@ -489,6 +489,11 @@
|
|||||||
"path": "github.com/go-ldap/ldap/v3/LICENSE",
|
"path": "github.com/go-ldap/ldap/v3/LICENSE",
|
||||||
"licenseText": "The MIT License (MIT)\n\nCopyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)\nPortions copyright (c) 2015-2016 go-ldap Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
|
"licenseText": "The MIT License (MIT)\n\nCopyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)\nPortions copyright (c) 2015-2016 go-ldap Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/go-redsync/redsync/v4",
|
||||||
|
"path": "github.com/go-redsync/redsync/v4/LICENSE",
|
||||||
|
"licenseText": "Copyright (c) 2023, Mahmud Ridwan\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n* Neither the name of the Redsync nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "github.com/go-sql-driver/mysql",
|
"name": "github.com/go-sql-driver/mysql",
|
||||||
"path": "github.com/go-sql-driver/mysql/LICENSE",
|
"path": "github.com/go-sql-driver/mysql/LICENSE",
|
||||||
@@ -624,11 +629,21 @@
|
|||||||
"path": "github.com/gorilla/sessions/LICENSE",
|
"path": "github.com/gorilla/sessions/LICENSE",
|
||||||
"licenseText": "Copyright (c) 2023 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
"licenseText": "Copyright (c) 2023 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/hashicorp/errwrap",
|
||||||
|
"path": "github.com/hashicorp/errwrap/LICENSE",
|
||||||
|
"licenseText": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. “Contributor”\n\n means each individual or legal entity that creates, contributes to the\n creation of, or owns Covered Software.\n\n1.2. “Contributor Version”\n\n means the combination of the Contributions of others (if any) used by a\n Contributor and that particular Contributor’s Contribution.\n\n1.3. “Contribution”\n\n means Covered Software of a particular Contributor.\n\n1.4. “Covered Software”\n\n means Source Code Form to which the initial Contributor has attached the\n notice in Exhibit A, the Executable Form of such Source Code Form, and\n Modifications of such Source Code Form, in each case including portions\n thereof.\n\n1.5. “Incompatible With Secondary Licenses”\n means\n\n a. that the initial Contributor has attached the notice described in\n Exhibit B to the Covered Software; or\n\n b. that the Covered Software was made available under the terms of version\n 1.1 or earlier of the License, but not also under the terms of a\n Secondary License.\n\n1.6. “Executable Form”\n\n means any form of the work other than Source Code Form.\n\n1.7. “Larger Work”\n\n means a work that combines Covered Software with other material, in a separate\n file or files, that is not Covered Software.\n\n1.8. “License”\n\n means this document.\n\n1.9. “Licensable”\n\n means having the right to grant, to the maximum extent possible, whether at the\n time of the initial grant or subsequently, any and all of the rights conveyed by\n this License.\n\n1.10. “Modifications”\n\n means any of the following:\n\n a. any file in Source Code Form that results from an addition to, deletion\n from, or modification of the contents of Covered Software; or\n\n b. any new file in Source Code Form that contains any Covered Software.\n\n1.11. “Patent Claims” of a Contributor\n\n means any patent claim(s), including without limitation, method, process,\n and apparatus claims, in any patent Licensable by such Contributor that\n would be infringed, but for the grant of the License, by the making,\n using, selling, offering for sale, having made, import, or transfer of\n either its Contributions or its Contributor Version.\n\n1.12. “Secondary License”\n\n means either the GNU General Public License, Version 2.0, the GNU Lesser\n General Public License, Version 2.1, the GNU Affero General Public\n License, Version 3.0, or any later versions of those licenses.\n\n1.13. “Source Code Form”\n\n means the form of the work preferred for making modifications.\n\n1.14. “You” (or “Your”)\n\n means an individual or a legal entity exercising rights under this\n License. For legal entities, “You” includes any entity that controls, is\n controlled by, or is under common control with You. For purposes of this\n definition, “control” means (a) the power, direct or indirect, to cause\n the direction or management of such entity, whether by contract or\n otherwise, or (b) ownership of more than fifty percent (50%) of the\n outstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\n Each Contributor hereby grants You a world-wide, royalty-free,\n non-exclusive license:\n\n a. under intellectual property rights (other than patent or trademark)\n Licensable by such Contributor to use, reproduce, make available,\n modify, display, perform, distribute, and otherwise exploit its\n Contributions, either on an unmodified basis, with Modifications, or as\n part of a Larger Work; and\n\n b. under Patent Claims of such Contributor to make, use, sell, offer for\n sale, have made, import, and otherwise transfer either its Contributions\n or its Contributor Version.\n\n2.2. Effective Date\n\n The licenses granted in Section 2.1 with respect to any Contribution become\n effective for each Contribution on the date the Contributor first distributes\n such Contribution.\n\n2.3. Limitations on Grant Scope\n\n The licenses granted in this Section 2 are the only rights granted under this\n License. No additional rights or licenses will be implied from the distribution\n or licensing of Covered Software under this License. Notwithstanding Section\n 2.1(b) above, no patent license is granted by a Contributor:\n\n a. for any code that a Contributor has removed from Covered Software; or\n\n b. for infringements caused by: (i) Your and any other third party’s\n modifications of Covered Software, or (ii) the combination of its\n Contributions with other software (except as part of its Contributor\n Version); or\n\n c. under Patent Claims infringed by Covered Software Line truncated
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "github.com/hashicorp/go-cleanhttp",
|
"name": "github.com/hashicorp/go-cleanhttp",
|
||||||
"path": "github.com/hashicorp/go-cleanhttp/LICENSE",
|
"path": "github.com/hashicorp/go-cleanhttp/LICENSE",
|
||||||
"licenseText": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. \"Contributor\"\n\n means each individual or legal entity that creates, contributes to the\n creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n\n means the combination of the Contributions of others (if any) used by a\n Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n\n means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n\n means Source Code Form to which the initial Contributor has attached the\n notice in Exhibit A, the Executable Form of such Source Code Form, and\n Modifications of such Source Code Form, in each case including portions\n thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n means\n\n a. that the initial Contributor has attached the notice described in\n Exhibit B to the Covered Software; or\n\n b. that the Covered Software was made available under the terms of\n version 1.1 or earlier of the License, but not also under the terms of\n a Secondary License.\n\n1.6. \"Executable Form\"\n\n means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n\n means a work that combines Covered Software with other material, in a\n separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n\n means this document.\n\n1.9. \"Licensable\"\n\n means having the right to grant, to the maximum extent possible, whether\n at the time of the initial grant or subsequently, any and all of the\n rights conveyed by this License.\n\n1.10. \"Modifications\"\n\n means any of the following:\n\n a. any file in Source Code Form that results from an addition to,\n deletion from, or modification of the contents of Covered Software; or\n\n b. any new file in Source Code Form that contains any Covered Software.\n\n1.11. \"Patent Claims\" of a Contributor\n\n means any patent claim(s), including without limitation, method,\n process, and apparatus claims, in any patent Licensable by such\n Contributor that would be infringed, but for the grant of the License,\n by the making, using, selling, offering for sale, having made, import,\n or transfer of either its Contributions or its Contributor Version.\n\n1.12. \"Secondary License\"\n\n means either the GNU General Public License, Version 2.0, the GNU Lesser\n General Public License, Version 2.1, the GNU Affero General Public\n License, Version 3.0, or any later versions of those licenses.\n\n1.13. \"Source Code Form\"\n\n means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n\n means an individual or a legal entity exercising rights under this\n License. For legal entities, \"You\" includes any entity that controls, is\n controlled by, or is under common control with You. For purposes of this\n definition, \"control\" means (a) the power, direct or indirect, to cause\n the direction or management of such entity, whether by contract or\n otherwise, or (b) ownership of more than fifty percent (50%) of the\n outstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\n Each Contributor hereby grants You a world-wide, royalty-free,\n non-exclusive license:\n\n a. under intellectual property rights (other than patent or trademark)\n Licensable by such Contributor to use, reproduce, make available,\n modify, display, perform, distribute, and otherwise exploit its\n Contributions, either on an unmodified basis, with Modifications, or\n as part of a Larger Work; and\n\n b. under Patent Claims of such Contributor to make, use, sell, offer for\n sale, have made, import, and otherwise transfer either its\n Contributions or its Contributor Version.\n\n2.2. Effective Date\n\n The licenses granted in Section 2.1 with respect to any Contribution\n become effective for each Contribution on the date the Contributor first\n distributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\n The licenses granted in this Section 2 are the only rights granted under\n this License. No additional rights or licenses will be implied from the\n distribution or licensing of Covered Software under this License.\n Notwithstanding Section 2.1(b) above, no patent license is granted by a\n Contributor:\n\n a. for any code that a Contributor has removed from Covered Software; or\n\n b. for infringements caused by: (i) Your and any other third party's\n modifications of Covered Software, or (ii) the combination of its\n Contributions with other software (except as part of its Contributor\n Version); or\n\n c. under Patent Claims infringed by Covered Software in the absence of\n its CLine truncated
|
"licenseText": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. \"Contributor\"\n\n means each individual or legal entity that creates, contributes to the\n creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n\n means the combination of the Contributions of others (if any) used by a\n Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n\n means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n\n means Source Code Form to which the initial Contributor has attached the\n notice in Exhibit A, the Executable Form of such Source Code Form, and\n Modifications of such Source Code Form, in each case including portions\n thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n means\n\n a. that the initial Contributor has attached the notice described in\n Exhibit B to the Covered Software; or\n\n b. that the Covered Software was made available under the terms of\n version 1.1 or earlier of the License, but not also under the terms of\n a Secondary License.\n\n1.6. \"Executable Form\"\n\n means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n\n means a work that combines Covered Software with other material, in a\n separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n\n means this document.\n\n1.9. \"Licensable\"\n\n means having the right to grant, to the maximum extent possible, whether\n at the time of the initial grant or subsequently, any and all of the\n rights conveyed by this License.\n\n1.10. \"Modifications\"\n\n means any of the following:\n\n a. any file in Source Code Form that results from an addition to,\n deletion from, or modification of the contents of Covered Software; or\n\n b. any new file in Source Code Form that contains any Covered Software.\n\n1.11. \"Patent Claims\" of a Contributor\n\n means any patent claim(s), including without limitation, method,\n process, and apparatus claims, in any patent Licensable by such\n Contributor that would be infringed, but for the grant of the License,\n by the making, using, selling, offering for sale, having made, import,\n or transfer of either its Contributions or its Contributor Version.\n\n1.12. \"Secondary License\"\n\n means either the GNU General Public License, Version 2.0, the GNU Lesser\n General Public License, Version 2.1, the GNU Affero General Public\n License, Version 3.0, or any later versions of those licenses.\n\n1.13. \"Source Code Form\"\n\n means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n\n means an individual or a legal entity exercising rights under this\n License. For legal entities, \"You\" includes any entity that controls, is\n controlled by, or is under common control with You. For purposes of this\n definition, \"control\" means (a) the power, direct or indirect, to cause\n the direction or management of such entity, whether by contract or\n otherwise, or (b) ownership of more than fifty percent (50%) of the\n outstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\n Each Contributor hereby grants You a world-wide, royalty-free,\n non-exclusive license:\n\n a. under intellectual property rights (other than patent or trademark)\n Licensable by such Contributor to use, reproduce, make available,\n modify, display, perform, distribute, and otherwise exploit its\n Contributions, either on an unmodified basis, with Modifications, or\n as part of a Larger Work; and\n\n b. under Patent Claims of such Contributor to make, use, sell, offer for\n sale, have made, import, and otherwise transfer either its\n Contributions or its Contributor Version.\n\n2.2. Effective Date\n\n The licenses granted in Section 2.1 with respect to any Contribution\n become effective for each Contribution on the date the Contributor first\n distributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\n The licenses granted in this Section 2 are the only rights granted under\n this License. No additional rights or licenses will be implied from the\n distribution or licensing of Covered Software under this License.\n Notwithstanding Section 2.1(b) above, no patent license is granted by a\n Contributor:\n\n a. for any code that a Contributor has removed from Covered Software; or\n\n b. for infringements caused by: (i) Your and any other third party's\n modifications of Covered Software, or (ii) the combination of its\n Contributions with other software (except as part of its Contributor\n Version); or\n\n c. under Patent Claims infringed by Covered Software in the absence of\n its CLine truncated
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/hashicorp/go-multierror",
|
||||||
|
"path": "github.com/hashicorp/go-multierror/LICENSE",
|
||||||
|
"licenseText": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. “Contributor”\n\n means each individual or legal entity that creates, contributes to the\n creation of, or owns Covered Software.\n\n1.2. “Contributor Version”\n\n means the combination of the Contributions of others (if any) used by a\n Contributor and that particular Contributor’s Contribution.\n\n1.3. “Contribution”\n\n means Covered Software of a particular Contributor.\n\n1.4. “Covered Software”\n\n means Source Code Form to which the initial Contributor has attached the\n notice in Exhibit A, the Executable Form of such Source Code Form, and\n Modifications of such Source Code Form, in each case including portions\n thereof.\n\n1.5. “Incompatible With Secondary Licenses”\n means\n\n a. that the initial Contributor has attached the notice described in\n Exhibit B to the Covered Software; or\n\n b. that the Covered Software was made available under the terms of version\n 1.1 or earlier of the License, but not also under the terms of a\n Secondary License.\n\n1.6. “Executable Form”\n\n means any form of the work other than Source Code Form.\n\n1.7. “Larger Work”\n\n means a work that combines Covered Software with other material, in a separate\n file or files, that is not Covered Software.\n\n1.8. “License”\n\n means this document.\n\n1.9. “Licensable”\n\n means having the right to grant, to the maximum extent possible, whether at the\n time of the initial grant or subsequently, any and all of the rights conveyed by\n this License.\n\n1.10. “Modifications”\n\n means any of the following:\n\n a. any file in Source Code Form that results from an addition to, deletion\n from, or modification of the contents of Covered Software; or\n\n b. any new file in Source Code Form that contains any Covered Software.\n\n1.11. “Patent Claims” of a Contributor\n\n means any patent claim(s), including without limitation, method, process,\n and apparatus claims, in any patent Licensable by such Contributor that\n would be infringed, but for the grant of the License, by the making,\n using, selling, offering for sale, having made, import, or transfer of\n either its Contributions or its Contributor Version.\n\n1.12. “Secondary License”\n\n means either the GNU General Public License, Version 2.0, the GNU Lesser\n General Public License, Version 2.1, the GNU Affero General Public\n License, Version 3.0, or any later versions of those licenses.\n\n1.13. “Source Code Form”\n\n means the form of the work preferred for making modifications.\n\n1.14. “You” (or “Your”)\n\n means an individual or a legal entity exercising rights under this\n License. For legal entities, “You” includes any entity that controls, is\n controlled by, or is under common control with You. For purposes of this\n definition, “control” means (a) the power, direct or indirect, to cause\n the direction or management of such entity, whether by contract or\n otherwise, or (b) ownership of more than fifty percent (50%) of the\n outstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\n Each Contributor hereby grants You a world-wide, royalty-free,\n non-exclusive license:\n\n a. under intellectual property rights (other than patent or trademark)\n Licensable by such Contributor to use, reproduce, make available,\n modify, display, perform, distribute, and otherwise exploit its\n Contributions, either on an unmodified basis, with Modifications, or as\n part of a Larger Work; and\n\n b. under Patent Claims of such Contributor to make, use, sell, offer for\n sale, have made, import, and otherwise transfer either its Contributions\n or its Contributor Version.\n\n2.2. Effective Date\n\n The licenses granted in Section 2.1 with respect to any Contribution become\n effective for each Contribution on the date the Contributor first distributes\n such Contribution.\n\n2.3. Limitations on Grant Scope\n\n The licenses granted in this Section 2 are the only rights granted under this\n License. No additional rights or licenses will be implied from the distribution\n or licensing of Covered Software under this License. Notwithstanding Section\n 2.1(b) above, no patent license is granted by a Contributor:\n\n a. for any code that a Contributor has removed from Covered Software; or\n\n b. for infringements caused by: (i) Your and any other third party’s\n modifications of Covered Software, or (ii) the combination of its\n Contributions with other software (except as part of its Contributor\n Version); or\n\n c. under Patent Claims infringed by Covered Software Line truncated
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "github.com/hashicorp/go-retryablehttp",
|
"name": "github.com/hashicorp/go-retryablehttp",
|
||||||
"path": "github.com/hashicorp/go-retryablehttp/LICENSE",
|
"path": "github.com/hashicorp/go-retryablehttp/LICENSE",
|
||||||
|
|||||||
@@ -2713,3 +2713,9 @@ LEVEL = Info
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; storage type
|
;; storage type
|
||||||
;STORAGE_TYPE = local
|
;STORAGE_TYPE = local
|
||||||
|
|
||||||
|
;[global_lock]
|
||||||
|
;; Lock service type, could be memory or redis
|
||||||
|
;SERVICE_TYPE = memory
|
||||||
|
;; Ignored for the "memory" type. For "redis" use something like `redis://127.0.0.1:6379/0`
|
||||||
|
;SERVICE_CONN_STR =
|
||||||
@@ -6,14 +6,22 @@ package globallock
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
defaultLocker Locker
|
defaultLocker Locker
|
||||||
initOnce sync.Once
|
initOnce sync.Once
|
||||||
initFunc = func() {
|
initFunc = func() {
|
||||||
// TODO: read the setting and initialize the default locker.
|
switch setting.GlobalLock.ServiceType {
|
||||||
// Before implementing this, don't use it.
|
case "redis":
|
||||||
|
defaultLocker = NewRedisLocker(setting.GlobalLock.ServiceConnStr)
|
||||||
|
case "memory":
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
defaultLocker = NewMemoryLocker()
|
||||||
|
}
|
||||||
} // define initFunc as a variable to make it possible to change it in tests
|
} // define initFunc as a variable to make it possible to change it in tests
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package setting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/nosql"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GlobalLock represents configuration of global lock
|
||||||
|
var GlobalLock = struct {
|
||||||
|
ServiceType string
|
||||||
|
ServiceConnStr string
|
||||||
|
}{
|
||||||
|
ServiceType: "memory",
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadGlobalLockFrom(rootCfg ConfigProvider) {
|
||||||
|
sec := rootCfg.Section("global_lock")
|
||||||
|
GlobalLock.ServiceType = sec.Key("SERVICE_TYPE").MustString("memory")
|
||||||
|
switch GlobalLock.ServiceType {
|
||||||
|
case "memory":
|
||||||
|
case "redis":
|
||||||
|
connStr := sec.Key("SERVICE_CONN_STR").String()
|
||||||
|
if connStr == "" {
|
||||||
|
log.Fatal("SERVICE_CONN_STR is empty for redis")
|
||||||
|
}
|
||||||
|
u := nosql.ToRedisURI(connStr)
|
||||||
|
if u == nil {
|
||||||
|
log.Fatal("SERVICE_CONN_STR %s is not a valid redis connection string", connStr)
|
||||||
|
}
|
||||||
|
GlobalLock.ServiceConnStr = connStr
|
||||||
|
default:
|
||||||
|
log.Fatal("Unknown sync lock service type: %s", GlobalLock.ServiceType)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package setting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLoadGlobalLockConfig(t *testing.T) {
|
||||||
|
t.Run("DefaultGlobalLockConfig", func(t *testing.T) {
|
||||||
|
iniStr := ``
|
||||||
|
cfg, err := NewConfigProviderFromData(iniStr)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
loadGlobalLockFrom(cfg)
|
||||||
|
assert.EqualValues(t, "memory", GlobalLock.ServiceType)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("RedisGlobalLockConfig", func(t *testing.T) {
|
||||||
|
iniStr := `
|
||||||
|
[global_lock]
|
||||||
|
SERVICE_TYPE = redis
|
||||||
|
SERVICE_CONN_STR = addrs=127.0.0.1:6379 db=0
|
||||||
|
`
|
||||||
|
cfg, err := NewConfigProviderFromData(iniStr)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
loadGlobalLockFrom(cfg)
|
||||||
|
assert.EqualValues(t, "redis", GlobalLock.ServiceType)
|
||||||
|
assert.EqualValues(t, "addrs=127.0.0.1:6379 db=0", GlobalLock.ServiceConnStr)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -147,6 +147,7 @@ func loadCommonSettingsFrom(cfg ConfigProvider) error {
|
|||||||
loadGitFrom(cfg)
|
loadGitFrom(cfg)
|
||||||
loadMirrorFrom(cfg)
|
loadMirrorFrom(cfg)
|
||||||
loadMarkupFrom(cfg)
|
loadMarkupFrom(cfg)
|
||||||
|
loadGlobalLockFrom(cfg)
|
||||||
loadOtherFrom(cfg)
|
loadOtherFrom(cfg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
package sync
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ExclusivePool is a pool of non-identical instances
|
|
||||||
// that only one instance with same identity is in the pool at a time.
|
|
||||||
// In other words, only instances with different identities can be in
|
|
||||||
// the pool the same time. If another instance with same identity tries
|
|
||||||
// to get into the pool, it hangs until previous instance left the pool.
|
|
||||||
//
|
|
||||||
// This pool is particularly useful for performing tasks on same resource
|
|
||||||
// on the file system in different goroutines.
|
|
||||||
type ExclusivePool struct {
|
|
||||||
lock sync.Mutex
|
|
||||||
|
|
||||||
// pool maintains locks for each instance in the pool.
|
|
||||||
pool map[string]*sync.Mutex
|
|
||||||
|
|
||||||
// count maintains the number of times an instance with same identity checks in
|
|
||||||
// to the pool, and should be reduced to 0 (removed from map) by checking out
|
|
||||||
// with same number of times.
|
|
||||||
// The purpose of count is to delete lock when count down to 0 and recycle memory
|
|
||||||
// from map object.
|
|
||||||
count map[string]int
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewExclusivePool initializes and returns a new ExclusivePool object.
|
|
||||||
func NewExclusivePool() *ExclusivePool {
|
|
||||||
return &ExclusivePool{
|
|
||||||
pool: make(map[string]*sync.Mutex),
|
|
||||||
count: make(map[string]int),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckIn checks in an instance to the pool and hangs while instance
|
|
||||||
// with same identity is using the lock.
|
|
||||||
func (p *ExclusivePool) CheckIn(identity string) {
|
|
||||||
p.lock.Lock()
|
|
||||||
|
|
||||||
lock, has := p.pool[identity]
|
|
||||||
if !has {
|
|
||||||
lock = &sync.Mutex{}
|
|
||||||
p.pool[identity] = lock
|
|
||||||
}
|
|
||||||
p.count[identity]++
|
|
||||||
|
|
||||||
p.lock.Unlock()
|
|
||||||
lock.Lock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckOut checks out an instance from the pool and releases the lock
|
|
||||||
// to let other instances with same identity to grab the lock.
|
|
||||||
func (p *ExclusivePool) CheckOut(identity string) {
|
|
||||||
p.lock.Lock()
|
|
||||||
defer p.lock.Unlock()
|
|
||||||
|
|
||||||
p.pool[identity].Unlock()
|
|
||||||
if p.count[identity] == 1 {
|
|
||||||
delete(p.pool, identity)
|
|
||||||
delete(p.count, identity)
|
|
||||||
} else {
|
|
||||||
p.count[identity]--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+10
-3
@@ -21,6 +21,7 @@ import (
|
|||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/gitrepo"
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
|
"code.gitea.io/gitea/modules/globallock"
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/process"
|
"code.gitea.io/gitea/modules/process"
|
||||||
@@ -334,9 +335,15 @@ func handler(items ...string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testPR(id int64) {
|
func testPR(id int64) {
|
||||||
pullWorkingPool.CheckIn(fmt.Sprint(id))
|
ctx := graceful.GetManager().HammerContext()
|
||||||
defer pullWorkingPool.CheckOut(fmt.Sprint(id))
|
releaser, err := globallock.Lock(ctx, getPullWorkingLockKey(id))
|
||||||
ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("Test PR[%d] from patch checking queue", id))
|
if err != nil {
|
||||||
|
log.Error("lock.Lock(): %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer releaser()
|
||||||
|
|
||||||
|
ctx, _, finished := process.GetManager().AddContext(ctx, fmt.Sprintf("Test PR[%d] from patch checking queue", id))
|
||||||
defer finished()
|
defer finished()
|
||||||
|
|
||||||
pr, err := issues_model.GetPullRequestByID(ctx, id)
|
pr, err := issues_model.GetPullRequestByID(ctx, id)
|
||||||
|
|||||||
+18
-7
@@ -23,6 +23,7 @@ import (
|
|||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/cache"
|
"code.gitea.io/gitea/modules/cache"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/globallock"
|
||||||
"code.gitea.io/gitea/modules/httplib"
|
"code.gitea.io/gitea/modules/httplib"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/references"
|
"code.gitea.io/gitea/modules/references"
|
||||||
@@ -169,9 +170,6 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U
|
|||||||
return fmt.Errorf("unable to load head repo: %w", err)
|
return fmt.Errorf("unable to load head repo: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pullWorkingPool.CheckIn(fmt.Sprint(pr.ID))
|
|
||||||
defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID))
|
|
||||||
|
|
||||||
prUnit, err := pr.BaseRepo.GetUnit(ctx, unit.TypePullRequests)
|
prUnit, err := pr.BaseRepo.GetUnit(ctx, unit.TypePullRequests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("pr.BaseRepo.GetUnit(unit.TypePullRequests): %v", err)
|
log.Error("pr.BaseRepo.GetUnit(unit.TypePullRequests): %v", err)
|
||||||
@@ -184,11 +182,18 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U
|
|||||||
return models.ErrInvalidMergeStyle{ID: pr.BaseRepo.ID, Style: mergeStyle}
|
return models.ErrInvalidMergeStyle{ID: pr.BaseRepo.ID, Style: mergeStyle}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
releaser, err := globallock.Lock(ctx, getPullWorkingLockKey(pr.ID))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("lock.Lock(): %v", err)
|
||||||
|
return fmt.Errorf("lock.Lock: %w", err)
|
||||||
|
}
|
||||||
|
defer releaser()
|
||||||
defer func() {
|
defer func() {
|
||||||
go AddTestPullRequestTask(doer, pr.BaseRepo.ID, pr.BaseBranch, false, "", "")
|
go AddTestPullRequestTask(doer, pr.BaseRepo.ID, pr.BaseBranch, false, "", "")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
_, err = doMergeAndPush(ctx, pr, doer, mergeStyle, expectedHeadCommitID, message, repo_module.PushTriggerPRMergeToBase)
|
_, err = doMergeAndPush(ctx, pr, doer, mergeStyle, expectedHeadCommitID, message, repo_module.PushTriggerPRMergeToBase)
|
||||||
|
releaser()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -487,10 +492,14 @@ func CheckPullBranchProtections(ctx context.Context, pr *issues_model.PullReques
|
|||||||
|
|
||||||
// MergedManually mark pr as merged manually
|
// MergedManually mark pr as merged manually
|
||||||
func MergedManually(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, commitID string) error {
|
func MergedManually(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, commitID string) error {
|
||||||
pullWorkingPool.CheckIn(fmt.Sprint(pr.ID))
|
releaser, err := globallock.Lock(ctx, getPullWorkingLockKey(pr.ID))
|
||||||
defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID))
|
if err != nil {
|
||||||
|
log.Error("lock.Lock(): %v", err)
|
||||||
|
return fmt.Errorf("lock.Lock: %w", err)
|
||||||
|
}
|
||||||
|
defer releaser()
|
||||||
|
|
||||||
if err := db.WithTx(ctx, func(ctx context.Context) error {
|
err = db.WithTx(ctx, func(ctx context.Context) error {
|
||||||
if err := pr.LoadBaseRepo(ctx); err != nil {
|
if err := pr.LoadBaseRepo(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -540,7 +549,9 @@ func MergedManually(ctx context.Context, pr *issues_model.PullRequest, doer *use
|
|||||||
return fmt.Errorf("SetMerged failed")
|
return fmt.Errorf("SetMerged failed")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
})
|
||||||
|
releaser()
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-5
@@ -25,20 +25,21 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/container"
|
"code.gitea.io/gitea/modules/container"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/gitrepo"
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
|
"code.gitea.io/gitea/modules/globallock"
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/json"
|
"code.gitea.io/gitea/modules/json"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
repo_module "code.gitea.io/gitea/modules/repository"
|
repo_module "code.gitea.io/gitea/modules/repository"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/sync"
|
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
gitea_context "code.gitea.io/gitea/services/context"
|
gitea_context "code.gitea.io/gitea/services/context"
|
||||||
issue_service "code.gitea.io/gitea/services/issue"
|
issue_service "code.gitea.io/gitea/services/issue"
|
||||||
notify_service "code.gitea.io/gitea/services/notify"
|
notify_service "code.gitea.io/gitea/services/notify"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: use clustered lock (unique queue? or *abuse* cache)
|
func getPullWorkingLockKey(prID int64) string {
|
||||||
var pullWorkingPool = sync.NewExclusivePool()
|
return fmt.Sprintf("pull_working_%d", prID)
|
||||||
|
}
|
||||||
|
|
||||||
// NewPullRequest creates new pull request with labels for repository.
|
// NewPullRequest creates new pull request with labels for repository.
|
||||||
func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *issues_model.Issue, labelIDs []int64, uuids []string, pr *issues_model.PullRequest, assigneeIDs []int64) error {
|
func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *issues_model.Issue, labelIDs []int64, uuids []string, pr *issues_model.PullRequest, assigneeIDs []int64) error {
|
||||||
@@ -202,8 +203,12 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *iss
|
|||||||
|
|
||||||
// ChangeTargetBranch changes the target branch of this pull request, as the given user.
|
// ChangeTargetBranch changes the target branch of this pull request, as the given user.
|
||||||
func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, targetBranch string) (err error) {
|
func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, targetBranch string) (err error) {
|
||||||
pullWorkingPool.CheckIn(fmt.Sprint(pr.ID))
|
releaser, err := globallock.Lock(ctx, getPullWorkingLockKey(pr.ID))
|
||||||
defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID))
|
if err != nil {
|
||||||
|
log.Error("lock.Lock(): %v", err)
|
||||||
|
return fmt.Errorf("lock.Lock: %w", err)
|
||||||
|
}
|
||||||
|
defer releaser()
|
||||||
|
|
||||||
// Current target branch is already the same
|
// Current target branch is already the same
|
||||||
if pr.BaseBranch == targetBranch {
|
if pr.BaseBranch == targetBranch {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"code.gitea.io/gitea/models/unit"
|
"code.gitea.io/gitea/models/unit"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/globallock"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/repository"
|
"code.gitea.io/gitea/modules/repository"
|
||||||
)
|
)
|
||||||
@@ -25,8 +26,12 @@ func Update(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.
|
|||||||
return fmt.Errorf("update of agit flow pull request's head branch is unsupported")
|
return fmt.Errorf("update of agit flow pull request's head branch is unsupported")
|
||||||
}
|
}
|
||||||
|
|
||||||
pullWorkingPool.CheckIn(fmt.Sprint(pr.ID))
|
releaser, err := globallock.Lock(ctx, getPullWorkingLockKey(pr.ID))
|
||||||
defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID))
|
if err != nil {
|
||||||
|
log.Error("lock.Lock(): %v", err)
|
||||||
|
return fmt.Errorf("lock.Lock: %w", err)
|
||||||
|
}
|
||||||
|
defer releaser()
|
||||||
|
|
||||||
diffCount, err := GetDiverging(ctx, pr)
|
diffCount, err := GetDiverging(ctx, pr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -18,16 +18,16 @@ import (
|
|||||||
project_model "code.gitea.io/gitea/models/project"
|
project_model "code.gitea.io/gitea/models/project"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"code.gitea.io/gitea/modules/globallock"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
repo_module "code.gitea.io/gitea/modules/repository"
|
repo_module "code.gitea.io/gitea/modules/repository"
|
||||||
"code.gitea.io/gitea/modules/sync"
|
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
notify_service "code.gitea.io/gitea/services/notify"
|
notify_service "code.gitea.io/gitea/services/notify"
|
||||||
)
|
)
|
||||||
|
|
||||||
// repoWorkingPool represents a working pool to order the parallel changes to the same repository
|
func getRepoWorkingLockKey(repoID int64) string {
|
||||||
// TODO: use clustered lock (unique queue? or *abuse* cache)
|
return fmt.Sprintf("repo_working_%d", repoID)
|
||||||
var repoWorkingPool = sync.NewExclusivePool()
|
}
|
||||||
|
|
||||||
// TransferOwnership transfers all corresponding setting from old user to new one.
|
// TransferOwnership transfers all corresponding setting from old user to new one.
|
||||||
func TransferOwnership(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository, teams []*organization.Team) error {
|
func TransferOwnership(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository, teams []*organization.Team) error {
|
||||||
@@ -42,12 +42,17 @@ func TransferOwnership(ctx context.Context, doer, newOwner *user_model.User, rep
|
|||||||
|
|
||||||
oldOwner := repo.Owner
|
oldOwner := repo.Owner
|
||||||
|
|
||||||
repoWorkingPool.CheckIn(fmt.Sprint(repo.ID))
|
releaser, err := globallock.Lock(ctx, getRepoWorkingLockKey(repo.ID))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("lock.Lock(): %v", err)
|
||||||
|
return fmt.Errorf("lock.Lock: %w", err)
|
||||||
|
}
|
||||||
|
defer releaser()
|
||||||
|
|
||||||
if err := transferOwnership(ctx, doer, newOwner.Name, repo); err != nil {
|
if err := transferOwnership(ctx, doer, newOwner.Name, repo); err != nil {
|
||||||
repoWorkingPool.CheckOut(fmt.Sprint(repo.ID))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
repoWorkingPool.CheckOut(fmt.Sprint(repo.ID))
|
releaser()
|
||||||
|
|
||||||
newRepo, err := repo_model.GetRepositoryByID(ctx, repo.ID)
|
newRepo, err := repo_model.GetRepositoryByID(ctx, repo.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -360,15 +365,20 @@ func ChangeRepositoryName(ctx context.Context, doer *user_model.User, repo *repo
|
|||||||
oldRepoName := repo.Name
|
oldRepoName := repo.Name
|
||||||
|
|
||||||
// Change repository directory name. We must lock the local copy of the
|
// Change repository directory name. We must lock the local copy of the
|
||||||
// repo so that we can atomically rename the repo path and updates the
|
// repo so that we can automatically rename the repo path and updates the
|
||||||
// local copy's origin accordingly.
|
// local copy's origin accordingly.
|
||||||
|
|
||||||
repoWorkingPool.CheckIn(fmt.Sprint(repo.ID))
|
releaser, err := globallock.Lock(ctx, getRepoWorkingLockKey(repo.ID))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("lock.Lock(): %v", err)
|
||||||
|
return fmt.Errorf("lock.Lock: %w", err)
|
||||||
|
}
|
||||||
|
defer releaser()
|
||||||
|
|
||||||
if err := changeRepositoryName(ctx, repo, newRepoName); err != nil {
|
if err := changeRepositoryName(ctx, repo, newRepoName); err != nil {
|
||||||
repoWorkingPool.CheckOut(fmt.Sprint(repo.ID))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
repoWorkingPool.CheckOut(fmt.Sprint(repo.ID))
|
releaser()
|
||||||
|
|
||||||
repo.Name = newRepoName
|
repo.Name = newRepoName
|
||||||
notify_service.RenameRepository(ctx, doer, repo, oldRepoName)
|
notify_service.RenameRepository(ctx, doer, repo, oldRepoName)
|
||||||
|
|||||||
+15
-8
@@ -18,19 +18,20 @@ import (
|
|||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/gitrepo"
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
|
"code.gitea.io/gitea/modules/globallock"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
repo_module "code.gitea.io/gitea/modules/repository"
|
repo_module "code.gitea.io/gitea/modules/repository"
|
||||||
"code.gitea.io/gitea/modules/sync"
|
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
asymkey_service "code.gitea.io/gitea/services/asymkey"
|
asymkey_service "code.gitea.io/gitea/services/asymkey"
|
||||||
repo_service "code.gitea.io/gitea/services/repository"
|
repo_service "code.gitea.io/gitea/services/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: use clustered lock (unique queue? or *abuse* cache)
|
|
||||||
var wikiWorkingPool = sync.NewExclusivePool()
|
|
||||||
|
|
||||||
const DefaultRemote = "origin"
|
const DefaultRemote = "origin"
|
||||||
|
|
||||||
|
func getWikiWorkingLockKey(repoID int64) string {
|
||||||
|
return fmt.Sprintf("wiki_working_%d", repoID)
|
||||||
|
}
|
||||||
|
|
||||||
// InitWiki initializes a wiki for repository,
|
// InitWiki initializes a wiki for repository,
|
||||||
// it does nothing when repository already has wiki.
|
// it does nothing when repository already has wiki.
|
||||||
func InitWiki(ctx context.Context, repo *repo_model.Repository) error {
|
func InitWiki(ctx context.Context, repo *repo_model.Repository) error {
|
||||||
@@ -89,8 +90,11 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
|
|||||||
if err = validateWebPath(newWikiName); err != nil {
|
if err = validateWebPath(newWikiName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
wikiWorkingPool.CheckIn(fmt.Sprint(repo.ID))
|
releaser, err := globallock.Lock(ctx, getWikiWorkingLockKey(repo.ID))
|
||||||
defer wikiWorkingPool.CheckOut(fmt.Sprint(repo.ID))
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer releaser()
|
||||||
|
|
||||||
if err = InitWiki(ctx, repo); err != nil {
|
if err = InitWiki(ctx, repo); err != nil {
|
||||||
return fmt.Errorf("InitWiki: %w", err)
|
return fmt.Errorf("InitWiki: %w", err)
|
||||||
@@ -250,8 +254,11 @@ func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
wikiWorkingPool.CheckIn(fmt.Sprint(repo.ID))
|
releaser, err := globallock.Lock(ctx, getWikiWorkingLockKey(repo.ID))
|
||||||
defer wikiWorkingPool.CheckOut(fmt.Sprint(repo.ID))
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer releaser()
|
||||||
|
|
||||||
if err = InitWiki(ctx, repo); err != nil {
|
if err = InitWiki(ctx, repo); err != nil {
|
||||||
return fmt.Errorf("InitWiki: %w", err)
|
return fmt.Errorf("InitWiki: %w", err)
|
||||||
|
|||||||
Reference in new issue
Block a user