-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocesser.go
65 lines (53 loc) · 1.5 KB
/
processer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package main
import (
"fmt"
"sync/atomic"
"github.com/gin-gonic/gin"
"golang.org/x/sync/semaphore"
)
var (
containerSemaphore = semaphore.NewWeighted(containerNum) // 定义容器数量的信号量
)
func coderunnerProcesser(c *gin.Context) {
var req struct {
Code string `json:"code"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": "无法解析 JSON 数据"})
return
}
// 尝试获取信号量,如果容器数量超出限制,会阻塞直到有空闲容器
if err := containerSemaphore.Acquire(c.Request.Context(), 1); err != nil {
c.JSON(500, gin.H{"error": "Internal error"})
return
}
// 使用通道来并发处理请求
responseChan := make(chan Response)
go func() {
defer containerSemaphore.Release(1) // 在 goroutine 结束时释放信号量
response, found := findCache(req.Code)
if found {
responseChan <- response
return
}
// 获取唯一的 goroutine ID 作为索引
thisContainerIndex := atomic.AddUint64(&containerIndex, 1)
thisContainerIndex %= containerNum
// containerName 是 default 和 index 粘起来
dirname := fmt.Sprint(thisContainerIndex)
//fmt.Println("containerName:", containerName)
createContainerAndFiles(dirname)
var err error
response, err = coderunner(req.Code, dirname)
if err != nil {
response.Status = 1
response.Err = err.Error()
} else {
response.Status = 0
insertCache(req.Code, response)
}
responseChan <- response
}()
response := <-responseChan
c.JSON(200, response)
}