|
1 | 1 | package routes
|
2 | 2 |
|
3 | 3 | import (
|
4 |
| - "bufio" |
5 |
| - "bytes" |
6 |
| - "fmt" |
7 |
| - "net/http" |
8 |
| - "os" |
9 |
| - "sort" |
10 |
| - "strconv" |
11 |
| - "strings" |
12 |
| - |
13 |
| - log "github.com/sirupsen/logrus" |
14 |
| - |
15 |
| - "github.com/gin-gonic/gin" |
16 |
| - "github.com/sablierapp/sablier/app/http/routes/models" |
17 |
| - "github.com/sablierapp/sablier/app/instance" |
18 | 4 | "github.com/sablierapp/sablier/app/sessions"
|
19 | 5 | "github.com/sablierapp/sablier/app/theme"
|
20 | 6 | "github.com/sablierapp/sablier/config"
|
21 | 7 | )
|
22 | 8 |
|
23 |
| -var osDirFS = os.DirFS |
24 |
| - |
25 | 9 | type ServeStrategy struct {
|
26 | 10 | Theme *theme.Themes
|
27 | 11 |
|
28 | 12 | SessionsManager sessions.Manager
|
29 | 13 | StrategyConfig config.Strategy
|
30 | 14 | SessionsConfig config.Sessions
|
31 | 15 | }
|
32 |
| - |
33 |
| -func NewServeStrategy(sessionsManager sessions.Manager, strategyConf config.Strategy, sessionsConf config.Sessions, themes *theme.Themes) *ServeStrategy { |
34 |
| - |
35 |
| - serveStrategy := &ServeStrategy{ |
36 |
| - Theme: themes, |
37 |
| - SessionsManager: sessionsManager, |
38 |
| - StrategyConfig: strategyConf, |
39 |
| - SessionsConfig: sessionsConf, |
40 |
| - } |
41 |
| - |
42 |
| - return serveStrategy |
43 |
| -} |
44 |
| - |
45 |
| -func (s *ServeStrategy) ServeDynamic(c *gin.Context) { |
46 |
| - request := models.DynamicRequest{ |
47 |
| - Theme: s.StrategyConfig.Dynamic.DefaultTheme, |
48 |
| - ShowDetails: s.StrategyConfig.Dynamic.ShowDetailsByDefault, |
49 |
| - RefreshFrequency: s.StrategyConfig.Dynamic.DefaultRefreshFrequency, |
50 |
| - SessionDuration: s.SessionsConfig.DefaultDuration, |
51 |
| - } |
52 |
| - |
53 |
| - if err := c.ShouldBind(&request); err != nil { |
54 |
| - c.AbortWithError(http.StatusBadRequest, err) |
55 |
| - return |
56 |
| - } |
57 |
| - |
58 |
| - var sessionState *sessions.SessionState |
59 |
| - if len(request.Names) > 0 { |
60 |
| - sessionState = s.SessionsManager.RequestSession(request.Names, request.SessionDuration) |
61 |
| - } else { |
62 |
| - sessionState = s.SessionsManager.RequestSessionGroup(request.Group, request.SessionDuration) |
63 |
| - } |
64 |
| - |
65 |
| - if sessionState == nil { |
66 |
| - c.AbortWithStatus(http.StatusNotFound) |
67 |
| - return |
68 |
| - } |
69 |
| - |
70 |
| - if sessionState.IsReady() { |
71 |
| - c.Header("X-Sablier-Session-Status", "ready") |
72 |
| - } else { |
73 |
| - c.Header("X-Sablier-Session-Status", "not-ready") |
74 |
| - } |
75 |
| - |
76 |
| - renderOptions := theme.Options{ |
77 |
| - DisplayName: request.DisplayName, |
78 |
| - ShowDetails: request.ShowDetails, |
79 |
| - SessionDuration: request.SessionDuration, |
80 |
| - RefreshFrequency: request.RefreshFrequency, |
81 |
| - InstanceStates: sessionStateToRenderOptionsInstanceState(sessionState), |
82 |
| - } |
83 |
| - |
84 |
| - buf := new(bytes.Buffer) |
85 |
| - writer := bufio.NewWriter(buf) |
86 |
| - if err := s.Theme.Render(request.Theme, renderOptions, writer); err != nil { |
87 |
| - log.Error(err) |
88 |
| - c.AbortWithError(http.StatusInternalServerError, err) |
89 |
| - return |
90 |
| - } |
91 |
| - writer.Flush() |
92 |
| - |
93 |
| - c.Header("Cache-Control", "no-cache") |
94 |
| - c.Header("Content-Type", "text/html") |
95 |
| - c.Header("Content-Length", strconv.Itoa(buf.Len())) |
96 |
| - c.Writer.Write(buf.Bytes()) |
97 |
| -} |
98 |
| - |
99 |
| -func (s *ServeStrategy) ServeBlocking(c *gin.Context) { |
100 |
| - request := models.BlockingRequest{ |
101 |
| - Timeout: s.StrategyConfig.Blocking.DefaultTimeout, |
102 |
| - } |
103 |
| - |
104 |
| - if err := c.ShouldBind(&request); err != nil { |
105 |
| - c.AbortWithError(http.StatusBadRequest, err) |
106 |
| - return |
107 |
| - } |
108 |
| - |
109 |
| - var sessionState *sessions.SessionState |
110 |
| - var err error |
111 |
| - if len(request.Names) > 0 { |
112 |
| - sessionState, err = s.SessionsManager.RequestReadySession(c.Request.Context(), request.Names, request.SessionDuration, request.Timeout) |
113 |
| - } else { |
114 |
| - sessionState, err = s.SessionsManager.RequestReadySessionGroup(c.Request.Context(), request.Group, request.SessionDuration, request.Timeout) |
115 |
| - } |
116 |
| - |
117 |
| - if err != nil { |
118 |
| - c.AbortWithError(http.StatusInternalServerError, err) |
119 |
| - return |
120 |
| - } |
121 |
| - |
122 |
| - if sessionState == nil { |
123 |
| - c.AbortWithStatus(http.StatusNotFound) |
124 |
| - return |
125 |
| - } |
126 |
| - |
127 |
| - if err != nil { |
128 |
| - c.Header("X-Sablier-Session-Status", "not-ready") |
129 |
| - c.JSON(http.StatusGatewayTimeout, map[string]interface{}{"error": err.Error()}) |
130 |
| - return |
131 |
| - } |
132 |
| - |
133 |
| - if sessionState.IsReady() { |
134 |
| - c.Header("X-Sablier-Session-Status", "ready") |
135 |
| - } else { |
136 |
| - c.Header("X-Sablier-Session-Status", "not-ready") |
137 |
| - } |
138 |
| - |
139 |
| - c.JSON(http.StatusOK, map[string]interface{}{"session": sessionState}) |
140 |
| -} |
141 |
| - |
142 |
| -func sessionStateToRenderOptionsInstanceState(sessionState *sessions.SessionState) (instances []theme.Instance) { |
143 |
| - if sessionState == nil { |
144 |
| - log.Warnf("sessionStateToRenderOptionsInstanceState: sessionState is nil") |
145 |
| - return |
146 |
| - } |
147 |
| - sessionState.Instances.Range(func(key, value any) bool { |
148 |
| - if value != nil { |
149 |
| - instances = append(instances, instanceStateToRenderOptionsRequestState(value.(sessions.InstanceState).Instance)) |
150 |
| - } else { |
151 |
| - log.Warnf("sessionStateToRenderOptionsInstanceState: sessionState instance is nil, key: %v", key) |
152 |
| - } |
153 |
| - |
154 |
| - return true |
155 |
| - }) |
156 |
| - |
157 |
| - sort.SliceStable(instances, func(i, j int) bool { |
158 |
| - return strings.Compare(instances[i].Name, instances[j].Name) == -1 |
159 |
| - }) |
160 |
| - |
161 |
| - return |
162 |
| -} |
163 |
| - |
164 |
| -func instanceStateToRenderOptionsRequestState(instanceState *instance.State) theme.Instance { |
165 |
| - |
166 |
| - var err error |
167 |
| - if instanceState.Message == "" { |
168 |
| - err = nil |
169 |
| - } else { |
170 |
| - err = fmt.Errorf(instanceState.Message) |
171 |
| - } |
172 |
| - |
173 |
| - return theme.Instance{ |
174 |
| - Name: instanceState.Name, |
175 |
| - Status: instanceState.Status, |
176 |
| - CurrentReplicas: instanceState.CurrentReplicas, |
177 |
| - DesiredReplicas: instanceState.DesiredReplicas, |
178 |
| - Error: err, |
179 |
| - } |
180 |
| -} |
0 commit comments