Fix status table race condition (#1835)
This commit is contained in:
		
							parent
							
								
									0f5b399e35
								
							
						
					
					
						commit
						bfb44f8854
					
				
					 5 changed files with 26 additions and 10 deletions
				
			
		|  | @ -1881,10 +1881,9 @@ func DeleteRepositoryArchives() error { | ||||||
| 
 | 
 | ||||||
| // DeleteOldRepositoryArchives deletes old repository archives.
 | // DeleteOldRepositoryArchives deletes old repository archives.
 | ||||||
| func DeleteOldRepositoryArchives() { | func DeleteOldRepositoryArchives() { | ||||||
| 	if taskStatusTable.IsRunning(archiveCleanup) { | 	if !taskStatusTable.StartIfNotRunning(archiveCleanup) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	taskStatusTable.Start(archiveCleanup) |  | ||||||
| 	defer taskStatusTable.Stop(archiveCleanup) | 	defer taskStatusTable.Stop(archiveCleanup) | ||||||
| 
 | 
 | ||||||
| 	log.Trace("Doing: ArchiveCleanup") | 	log.Trace("Doing: ArchiveCleanup") | ||||||
|  | @ -2025,10 +2024,9 @@ const ( | ||||||
| 
 | 
 | ||||||
| // GitFsck calls 'git fsck' to check repository health.
 | // GitFsck calls 'git fsck' to check repository health.
 | ||||||
| func GitFsck() { | func GitFsck() { | ||||||
| 	if taskStatusTable.IsRunning(gitFsck) { | 	if !taskStatusTable.StartIfNotRunning(gitFsck) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	taskStatusTable.Start(gitFsck) |  | ||||||
| 	defer taskStatusTable.Stop(gitFsck) | 	defer taskStatusTable.Stop(gitFsck) | ||||||
| 
 | 
 | ||||||
| 	log.Trace("Doing: GitFsck") | 	log.Trace("Doing: GitFsck") | ||||||
|  | @ -2097,10 +2095,9 @@ func repoStatsCheck(checker *repoChecker) { | ||||||
| 
 | 
 | ||||||
| // CheckRepoStats checks the repository stats
 | // CheckRepoStats checks the repository stats
 | ||||||
| func CheckRepoStats() { | func CheckRepoStats() { | ||||||
| 	if taskStatusTable.IsRunning(checkRepos) { | 	if !taskStatusTable.StartIfNotRunning(checkRepos) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	taskStatusTable.Start(checkRepos) |  | ||||||
| 	defer taskStatusTable.Stop(checkRepos) | 	defer taskStatusTable.Stop(checkRepos) | ||||||
| 
 | 
 | ||||||
| 	log.Trace("Doing: CheckRepoStats") | 	log.Trace("Doing: CheckRepoStats") | ||||||
|  |  | ||||||
|  | @ -202,10 +202,9 @@ func DeleteMirrorByRepoID(repoID int64) error { | ||||||
| 
 | 
 | ||||||
| // MirrorUpdate checks and updates mirror repositories.
 | // MirrorUpdate checks and updates mirror repositories.
 | ||||||
| func MirrorUpdate() { | func MirrorUpdate() { | ||||||
| 	if taskStatusTable.IsRunning(mirrorUpdate) { | 	if !taskStatusTable.StartIfNotRunning(mirrorUpdate) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	taskStatusTable.Start(mirrorUpdate) |  | ||||||
| 	defer taskStatusTable.Stop(mirrorUpdate) | 	defer taskStatusTable.Stop(mirrorUpdate) | ||||||
| 
 | 
 | ||||||
| 	log.Trace("Doing: MirrorUpdate") | 	log.Trace("Doing: MirrorUpdate") | ||||||
|  |  | ||||||
|  | @ -1334,10 +1334,9 @@ func GetWatchedRepos(userID int64, private bool) ([]*Repository, error) { | ||||||
| 
 | 
 | ||||||
| // SyncExternalUsers is used to synchronize users with external authorization source
 | // SyncExternalUsers is used to synchronize users with external authorization source
 | ||||||
| func SyncExternalUsers() { | func SyncExternalUsers() { | ||||||
| 	if taskStatusTable.IsRunning(syncExternalUsers) { | 	if !taskStatusTable.StartIfNotRunning(syncExternalUsers) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	taskStatusTable.Start(syncExternalUsers) |  | ||||||
| 	defer taskStatusTable.Stop(syncExternalUsers) | 	defer taskStatusTable.Stop(syncExternalUsers) | ||||||
| 
 | 
 | ||||||
| 	log.Trace("Doing: SyncExternalUsers") | 	log.Trace("Doing: SyncExternalUsers") | ||||||
|  |  | ||||||
|  | @ -24,6 +24,18 @@ func NewStatusTable() *StatusTable { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // StartIfNotRunning sets value of given name to true if not already in pool.
 | ||||||
|  | // Returns whether set value was set to true
 | ||||||
|  | func (p *StatusTable) StartIfNotRunning(name string) bool { | ||||||
|  | 	p.lock.Lock() | ||||||
|  | 	_, ok := p.pool[name] | ||||||
|  | 	if !ok { | ||||||
|  | 		p.pool[name] = struct{}{} | ||||||
|  | 	} | ||||||
|  | 	p.lock.Unlock() | ||||||
|  | 	return !ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Start sets value of given name to true in the pool.
 | // Start sets value of given name to true in the pool.
 | ||||||
| func (p *StatusTable) Start(name string) { | func (p *StatusTable) Start(name string) { | ||||||
| 	p.lock.Lock() | 	p.lock.Lock() | ||||||
|  |  | ||||||
|  | @ -18,6 +18,15 @@ func Test_StatusTable(t *testing.T) { | ||||||
| 	table.Start("xyz") | 	table.Start("xyz") | ||||||
| 	assert.True(t, table.IsRunning("xyz")) | 	assert.True(t, table.IsRunning("xyz")) | ||||||
| 
 | 
 | ||||||
|  | 	assert.False(t, table.StartIfNotRunning("xyz")) | ||||||
|  | 	assert.True(t, table.IsRunning("xyz")) | ||||||
|  | 
 | ||||||
|  | 	table.Stop("xyz") | ||||||
|  | 	assert.False(t, table.IsRunning("xyz")) | ||||||
|  | 
 | ||||||
|  | 	assert.True(t, table.StartIfNotRunning("xyz")) | ||||||
|  | 	assert.True(t, table.IsRunning("xyz")) | ||||||
|  | 
 | ||||||
| 	table.Stop("xyz") | 	table.Stop("xyz") | ||||||
| 	assert.False(t, table.IsRunning("xyz")) | 	assert.False(t, table.IsRunning("xyz")) | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue