handlerinfo.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package appsrv
  15. import (
  16. "context"
  17. "net/http"
  18. "strings"
  19. "time"
  20. )
  21. type handlerRequestCounter struct {
  22. hit int64
  23. duration float64
  24. }
  25. type TProcessTimeoutCallback func(*SHandlerInfo, *http.Request) time.Duration
  26. type TWorkerManagerCallback func(*SHandlerInfo, *http.Request) *SWorkerManager
  27. type SHandlerInfo struct {
  28. method string
  29. path []string
  30. name string
  31. handler func(context.Context, http.ResponseWriter, *http.Request)
  32. metadata map[string]interface{}
  33. tags map[string]string
  34. counter2XX handlerRequestCounter
  35. counter4XX handlerRequestCounter
  36. counter5XX handlerRequestCounter
  37. skipLog bool
  38. processTimeout time.Duration
  39. processTimeoutCallback TProcessTimeoutCallback
  40. workerManager *SWorkerManager
  41. workerManagerCallback TWorkerManagerCallback
  42. }
  43. func (hi *SHandlerInfo) fetchProcessTimeout(r *http.Request) time.Duration {
  44. if hi.processTimeoutCallback != nil {
  45. tm := hi.processTimeoutCallback(hi, r)
  46. if tm < hi.processTimeout {
  47. tm = hi.processTimeout
  48. }
  49. return tm
  50. } else {
  51. return hi.processTimeout
  52. }
  53. }
  54. func (hi *SHandlerInfo) SetProcessTimeoutCallback(callback TProcessTimeoutCallback) *SHandlerInfo {
  55. hi.processTimeoutCallback = callback
  56. return hi
  57. }
  58. func (hi *SHandlerInfo) SetProcessTimeout(to time.Duration) *SHandlerInfo {
  59. hi.processTimeout = to
  60. return hi
  61. }
  62. func (hi *SHandlerInfo) SetProcessNoTimeout() *SHandlerInfo {
  63. hi.processTimeout = -1
  64. return hi
  65. }
  66. func (hi *SHandlerInfo) fetchWorkerManager(r *http.Request) *SWorkerManager {
  67. if hi.workerManagerCallback != nil {
  68. wm := hi.workerManagerCallback(hi, r)
  69. if wm != nil {
  70. return wm
  71. }
  72. }
  73. return hi.workerManager
  74. }
  75. func (hi *SHandlerInfo) SetWorkerManagerCallback(callback TWorkerManagerCallback) *SHandlerInfo {
  76. hi.workerManagerCallback = callback
  77. return hi
  78. }
  79. func (hi *SHandlerInfo) SetWorkerManager(workerMan *SWorkerManager) *SHandlerInfo {
  80. hi.workerManager = workerMan
  81. return hi
  82. }
  83. func (hi *SHandlerInfo) ClearWorkerManager() *SHandlerInfo {
  84. hi.workerManager = nil
  85. return hi
  86. }
  87. func (this *SHandlerInfo) GetName(params map[string]string) string {
  88. if len(this.name) > 0 {
  89. return this.name
  90. }
  91. path := make([]string, len(this.path)+1)
  92. path[0] = strings.ToLower(this.method)
  93. for i, seg := range this.path {
  94. if params != nil {
  95. rep, ok := params[seg]
  96. if ok {
  97. seg = rep
  98. }
  99. }
  100. path[i+1] = strings.ToLower(seg)
  101. }
  102. return strings.Join(path, "_")
  103. }
  104. func (this *SHandlerInfo) GetTags() map[string]string {
  105. return this.tags
  106. }
  107. func NewHandlerInfo(method string, path []string, handler func(context.Context, http.ResponseWriter, *http.Request), metadata map[string]interface{}, name string, tags map[string]string) *SHandlerInfo {
  108. return newHandlerInfo(method, path, handler, metadata, name, tags)
  109. }
  110. func newHandlerInfo(method string, path []string, handler func(context.Context, http.ResponseWriter, *http.Request), metadata map[string]interface{}, name string, tags map[string]string) *SHandlerInfo {
  111. hand := SHandlerInfo{method: method, path: path,
  112. handler: handler,
  113. metadata: metadata,
  114. name: name,
  115. tags: tags}
  116. return &hand
  117. }
  118. func (hi *SHandlerInfo) SetMethod(method string) *SHandlerInfo {
  119. hi.method = method
  120. return hi
  121. }
  122. func (hi *SHandlerInfo) SetPath(path string) *SHandlerInfo {
  123. hi.path = SplitPath(path)
  124. return hi
  125. }
  126. func (hi *SHandlerInfo) SetHandler(hand func(context.Context, http.ResponseWriter, *http.Request)) *SHandlerInfo {
  127. hi.handler = hand
  128. return hi
  129. }
  130. func (hi *SHandlerInfo) SetMetadata(meta map[string]interface{}) *SHandlerInfo {
  131. hi.metadata = meta
  132. return hi
  133. }
  134. func (hi *SHandlerInfo) SetName(name string) *SHandlerInfo {
  135. hi.name = name
  136. return hi
  137. }
  138. func (hi *SHandlerInfo) SetTags(tags map[string]string) *SHandlerInfo {
  139. hi.tags = tags
  140. return hi
  141. }
  142. func (hi *SHandlerInfo) SetSkipLog(skip bool) *SHandlerInfo {
  143. hi.skipLog = skip
  144. return hi
  145. }
  146. func (hi *SHandlerInfo) GetAppParams(params map[string]string, path []string) *SAppParams {
  147. appParams := SAppParams{}
  148. appParams.Name = hi.GetName(params)
  149. appParams.SkipLog = hi.skipLog
  150. appParams.Params = params
  151. appParams.Path = path
  152. return &appParams
  153. }