Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: chenjie199234/Corelib
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.0.62
Choose a base ref
...
head repository: chenjie199234/Corelib
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref

Commits on Apr 10, 2022

  1. update

    chenjie199234 committed Apr 10, 2022
    Copy the full SHA
    c501880 View commit details
  2. update

    chenjie199234 committed Apr 10, 2022
    Copy the full SHA
    3a9a1ad View commit details
  3. update

    chenjie199234 committed Apr 10, 2022
    Copy the full SHA
    4548d17 View commit details

Commits on Apr 11, 2022

  1. update

    chenjie199234 committed Apr 11, 2022
    Copy the full SHA
    3805b3c View commit details
  2. update

    chenjie199234 committed Apr 11, 2022
    Copy the full SHA
    7bf4fda View commit details

Commits on Apr 13, 2022

  1. update

    chenjie199234 committed Apr 13, 2022
    Copy the full SHA
    9bbda52 View commit details
  2. update

    chenjie199234 committed Apr 13, 2022
    Copy the full SHA
    4901398 View commit details

Commits on Apr 16, 2022

  1. update

    chenjie199234 committed Apr 16, 2022
    Copy the full SHA
    dc04cd2 View commit details
  2. update

    chenjie199234 committed Apr 16, 2022
    Copy the full SHA
    e9c2049 View commit details
  3. update

    chenjie199234 committed Apr 16, 2022
    Copy the full SHA
    2023fed View commit details
  4. update

    chenjie199234 committed Apr 16, 2022
    Copy the full SHA
    9b28207 View commit details

Commits on Apr 18, 2022

  1. update

    chenjie199234 committed Apr 18, 2022
    Copy the full SHA
    68697ca View commit details

Commits on Apr 23, 2022

  1. update

    chenjie199234 committed Apr 23, 2022
    Copy the full SHA
    6bc4d7a View commit details

Commits on Apr 24, 2022

  1. update

    chenjie199234 committed Apr 24, 2022
    Copy the full SHA
    44405d4 View commit details

Commits on Apr 25, 2022

  1. update

    chenjie199234 committed Apr 25, 2022
    Copy the full SHA
    f8dbc92 View commit details
  2. update

    chenjie199234 committed Apr 25, 2022
    Copy the full SHA
    6d62599 View commit details

Commits on Apr 28, 2022

  1. update

    chenjie199234 committed Apr 28, 2022
    Copy the full SHA
    d9f8283 View commit details

Commits on Apr 30, 2022

  1. update

    chenjie199234 committed Apr 30, 2022
    Copy the full SHA
    5a2ee5b View commit details
  2. update

    chenjie199234 committed Apr 30, 2022
    Copy the full SHA
    cb6f690 View commit details
  3. update

    chenjie199234 committed Apr 30, 2022
    Copy the full SHA
    6f5de6e View commit details

Commits on May 14, 2022

  1. update

    chenjie199234 committed May 14, 2022
    Copy the full SHA
    6abf468 View commit details
  2. update

    chenjie199234 committed May 14, 2022
    Copy the full SHA
    3164785 View commit details
  3. update

    chenjie199234 committed May 14, 2022
    Copy the full SHA
    dddff29 View commit details
  4. update

    chenjie199234 committed May 14, 2022
    Copy the full SHA
    43c8841 View commit details

Commits on May 17, 2022

  1. update

    chenjie199234 committed May 17, 2022
    Copy the full SHA
    dc3bcfd View commit details

Commits on May 18, 2022

  1. update

    chenjie199234 committed May 18, 2022
    Copy the full SHA
    bb04a8d View commit details
  2. update

    chenjie199234 committed May 18, 2022
    Copy the full SHA
    e72155e View commit details
  3. update

    chenjie199234 committed May 18, 2022
    Copy the full SHA
    28318e4 View commit details
  4. update

    chenjie199234 committed May 18, 2022
    Copy the full SHA
    e57e4f2 View commit details
  5. update

    chenjie199234 committed May 18, 2022
    Copy the full SHA
    70a0549 View commit details
  6. update

    chenjie199234 committed May 18, 2022
    Copy the full SHA
    c3e6c1f View commit details
  7. update

    chenjie199234 committed May 18, 2022
    Copy the full SHA
    ec54ec3 View commit details

Commits on May 19, 2022

  1. update

    chenjie199234 committed May 19, 2022
    Copy the full SHA
    ec34f90 View commit details
  2. update

    chenjie199234 committed May 19, 2022
    Copy the full SHA
    dfc6946 View commit details
  3. upadte

    chenjie199234 committed May 19, 2022
    Copy the full SHA
    70fb75f View commit details

Commits on May 20, 2022

  1. update

    chenjie199234 committed May 20, 2022
    Copy the full SHA
    8353c55 View commit details
  2. update

    chenjie199234 committed May 20, 2022
    Copy the full SHA
    66bfa41 View commit details
  3. update

    chenjie199234 committed May 20, 2022
    Copy the full SHA
    48f46c0 View commit details
  4. update

    chenjie199234 committed May 20, 2022
    Copy the full SHA
    4edcb72 View commit details

Commits on May 21, 2022

  1. update

    chenjie199234 committed May 21, 2022
    Copy the full SHA
    5f8ae1f View commit details

Commits on May 31, 2022

  1. update

    chenjie199234 committed May 31, 2022
    Copy the full SHA
    4a50733 View commit details
  2. update

    chenjie199234 committed May 31, 2022
    Copy the full SHA
    f91116c View commit details

Commits on Jun 1, 2022

  1. update

    chenjie199234 committed Jun 1, 2022
    Copy the full SHA
    785cc25 View commit details
  2. update

    chenjie199234 committed Jun 1, 2022
    Copy the full SHA
    07dc3b5 View commit details
  3. update

    chenjie199234 committed Jun 1, 2022
    Copy the full SHA
    20a00b5 View commit details
  4. update

    chenjie199234 committed Jun 1, 2022
    Copy the full SHA
    2dea7b6 View commit details

Commits on Jun 8, 2022

  1. update

    chenjie committed Jun 8, 2022
    Copy the full SHA
    f5d871c View commit details
  2. update

    chenjie committed Jun 8, 2022
    Copy the full SHA
    d8113ca View commit details
  3. update

    chenjie committed Jun 8, 2022
    Copy the full SHA
    88b70a3 View commit details

Commits on Jun 10, 2022

  1. update

    chenjie committed Jun 10, 2022
    Copy the full SHA
    80259d2 View commit details
Showing with 24,060 additions and 11,972 deletions.
  1. +140 −1 Corelib.drawio
  2. BIN Corelib.jpg
  3. +22 −22 README.md
  4. +115 −0 cerror/cerror.go
  5. +146 −0 cerror/cerror.pb.go
  6. +8 −0 cerror/cerror.proto
  7. +61 −0 cerror/const.go
  8. +295 −153 cgrpc/balancer.go
  9. +235 −154 cgrpc/client.go
  10. +146 −0 cgrpc/clientcontext.go
  11. +0 −104 cgrpc/context.go
  12. +89 −0 cgrpc/error.go
  13. +48 −11 cgrpc/mids/mids.go
  14. +0 −97 cgrpc/picker.go
  15. +383 −69 cgrpc/protoc-gen-go-cgrpc/cgrpc.go
  16. +37 −14 cgrpc/protoc-gen-go-cgrpc/main.go
  17. +32 −167 cgrpc/protoc-gen-go-cgrpc/test/test.proto
  18. +0 −116 cgrpc/resolver.go
  19. +348 −149 cgrpc/server.go
  20. +30 −0 cgrpc/server_for_pick.go
  21. +290 −0 cgrpc/servercontext.go
  22. +2 −2 codegen/README.md
  23. +269 −209 codegen/main.go
  24. +29 −0 codegen/tml/api/api.go
  25. +0 −57 codegen/tml/api/client/client.go
  26. +33 −31 codegen/tml/api/status/template_status.go
  27. +26 −25 codegen/tml/api/sub/template_sub.go
  28. +170 −87 codegen/tml/cmd/template_cmd.go
  29. +482 −544 codegen/tml/config/template_config.go
  30. +134 −105 codegen/tml/configfile/template_configfile.go
  31. +70 −71 codegen/tml/dao/sub/template_sub.go
  32. +65 −103 codegen/tml/dao/template_dao.go
  33. +263 −0 codegen/tml/deploy/deploy.go
  34. +48 −37 codegen/tml/ecode/ecode.go
  35. +18 −26 codegen/tml/git/template_ignore.go
  36. +25 −31 codegen/tml/gomod/template_gomod.go
  37. +163 −0 codegen/tml/html/html.go
  38. +0 −228 codegen/tml/kubernetes/kubernetes.go
  39. +129 −33 codegen/tml/mainfile/template_main.go
  40. +13 −23 codegen/tml/model/sub/template_dub.go
  41. +44 −21 codegen/tml/model/template_model.go
  42. +39 −37 codegen/tml/readme/template_readme.go
  43. +59 −61 codegen/tml/server/xcrpc/template_xcrpc.go
  44. +59 −61 codegen/tml/server/xgrpc/template_xgrpc.go
  45. +92 −0 codegen/tml/server/xraw/template_xraw.go
  46. +71 −77 codegen/tml/server/xweb/template_xweb.go
  47. +101 −0 codegen/tml/service/raw/template_serviceraw.go
  48. +55 −40 codegen/tml/service/status/template_servicestatus.go
  49. +36 −34 codegen/tml/service/sub/template_sub.go
  50. +26 −27 codegen/tml/service/template_service.go
  51. +26 −0 codegen/tml/util/util.go
  52. +3 −3 container/hashtree/fixedhashtree.go
  53. +3 −3 container/hashtree/flexiblehashtree.go
  54. +9 −9 { → container}/id/id.go
  55. 0 { → container}/id/id_test.go
  56. +92 −0 container/list/blocklist.go
  57. +33 −0 container/list/blocklist_test.go
  58. +19 −11 container/list/list.go
  59. +162 −1 container/list/list_test.go
  60. +7 −7 container/lru/lru.go
  61. +13 −6 container/ring/ring.go
  62. +92 −0 container/stack/blockstack.go
  63. +8 −0 container/stack/blockstack_test.go
  64. +17 −9 container/stack/stack.go
  65. +1 −1 container/stack/stack_test.go
  66. +242 −0 container/trie/trie.go
  67. +105 −0 container/trie/trie_test.go
  68. +3 −0 cotel/const.go
  69. +287 −0 cotel/cotel.go
  70. +177 −0 cotel/cpu.go
  71. +18 −0 cotel/golang.go
  72. +122 −0 cotel/mem.go
  73. +88 −157 crpc/balancer.go
  74. +344 −252 crpc/client.go
  75. +231 −0 crpc/clientcontext.go
  76. +0 −116 crpc/context.go
  77. +48 −12 crpc/mids/mids.go
  78. +230 −110 crpc/msg.pb.go
  79. +22 −11 crpc/msg.proto
  80. +0 −97 crpc/picker.go
  81. +381 −76 crpc/protoc-gen-go-crpc/crpc.go
  82. +37 −14 crpc/protoc-gen-go-crpc/main.go
  83. +31 −167 crpc/protoc-gen-go-crpc/test/test.proto
  84. +0 −85 crpc/resolver.go
  85. +164 −0 crpc/rw.go
  86. +336 −298 crpc/server.go
  87. +125 −0 crpc/server_for_pick.go
  88. +344 −0 crpc/servercontext.go
  89. +57 −0 discover/discover.go
  90. +33 −0 discover/discover_test.go
  91. +222 −0 discover/dns.go
  92. +408 −0 discover/kubernetes.go
  93. +173 −0 discover/static.go
  94. +186 −0 email/email.go
  95. +0 −35 error/const.go
  96. +0 −128 error/error.go
  97. +0 −162 error/error.pb.go
  98. +0 −8 error/error.proto
  99. +0 −12 error/error_test.go
  100. +89 −10 go.mod
  101. +265 −117 go.sum
  102. +253 −0 internal/picker/picker.go
  103. +76 −0 internal/resolver/resolver.go
  104. +15 −0 internal/version/version.go
  105. +0 −255 log/log.go
  106. +0 −24 log/log_test.go
  107. +49 −20 metadata/metadata.go
  108. +146 −0 mids/access.go
  109. +0 −32 mids/access_key.go
  110. +8 −0 mids/access_test.go
  111. +118 −0 mids/ip.go
  112. +27 −0 mids/ip_test.go
  113. +202 −104 mids/rate.go
  114. +56 −0 mids/rate_test.go
  115. +104 −0 mids/session.go
  116. +67 −0 mids/session_test.go
  117. +63 −0 mids/token.go
  118. +38 −0 mids/token_test.go
  119. +236 −0 mongo/mongo.go
  120. +30 −0 mongo/mongo_test.go
  121. +0 −1,024 monitor/monitor.go
  122. +0 −42 monitor/monitor_test.go
  123. +214 −0 mysql/mysql.go
  124. +43 −0 mysql/mysql_test.go
  125. +667 −0 mysql/operator.go
  126. +316 −204 pbex/pbex.go
  127. +68 −68 pbex/pbex.pb.go
  128. +7 −7 pbex/pbex.proto
  129. +19 −15 pbex/protoc-gen-go-pbex/main.go
  130. +6 −5 pbex/protoc-gen-go-pbex/pbex.go
  131. +136 −153 pbex/protoc-gen-go-pbex/test/test.proto
  132. +65 −0 pool/bpool/bpool.go
  133. +0 −582 pool/bufpool.go
  134. +0 −63 pool/bufpool_test.go
  135. +135 −0 pool/cpool/cpool.go
  136. +0 −40 pool/iopool.go
  137. +27 −0 pool/rpool/rpool.go
  138. +28 −0 pool/wpool/wpool.go
  139. +1 −1 proto.bat
  140. +1 −1 proto.sh
  141. +145 −158 redis/bloom.go
  142. +57 −0 redis/bloom_test.go
  143. +118 −0 redis/broadcast.go
  144. +163 −0 redis/broadcast_test.go
  145. +0 −189 redis/listmq.go
  146. +169 −0 redis/prioritymq.go
  147. +135 −0 redis/prioritymq_test.go
  148. +39 −43 redis/ratelimit.go
  149. +112 −0 redis/ratelimit_test.go
  150. +283 −122 redis/redis.go
  151. +26 −0 redis/redis_test.go
  152. +93 −0 redis/unicast.go
  153. +62 −0 redis/unicast_test.go
  154. +134 −0 redis/verifycode.go
  155. +215 −0 redis/verifycode_test.go
  156. +11 −25 rotatefile/rotatefile.go
  157. +4 −4 rotatefile/rotatefile_test.go
  158. +54 −0 secure/aes.go
  159. +21 −0 secure/aes_test.go
  160. +21 −0 secure/padding.go
  161. +42 −0 secure/sign.go
  162. +16 −0 secure/sign_test.go
  163. +55 −44 stream/config.go
  164. +290 −179 stream/conn.go
  165. +78 −69 stream/connmng.go
  166. +21 −9 stream/instance.go
  167. +0 −234 stream/msg.go
  168. +147 −155 stream/peer.go
  169. +5 −6 stream/server_test.go
  170. +7 −8 stream/tcpclient_test.go
  171. +0 −249 stream/ws.go
  172. +12 −13 stream/wsclient_test.go
  173. +416 −0 superd/app.go
  174. +0 −536 superd/group.go
  175. +99 −53 superd/process.go
  176. +123 −109 superd/super.go
  177. +48 −48 superd/superd_test.go
  178. +0 −115 superd/util.go
  179. +0 −214 trace/trace.go
  180. +0 −15 trace/trace_test.go
  181. +27 −133 util/common/common.go
  182. +8 −99 util/common/common_test.go
  183. +66 −0 util/common/hash.go
  184. +191 −0 util/ctime/time.go
  185. +30 −0 util/ctime/time_test.go
  186. +1 −1 util/egroup/egroup.go
  187. +80 −0 util/graceful/graceful.go
  188. +39 −0 util/graceful/graceful_test.go
  189. +11 −1 util/host/host.go
  190. +72 −39 util/name/name.go
  191. +1 −1 util/{singlecall/singlecall.go → oneshot/oneshot.go}
  192. +2 −2 util/{singlecall/singlecall_test.go → oneshot/oneshot_test.go}
  193. +0 −171 util/time/time.go
  194. +0 −26 util/time/time_test.go
  195. +64 −0 util/waitwake/waitwake.go
  196. +154 −0 web/balancer.go
  197. +343 −206 web/client.go
  198. +96 −109 web/context.go
  199. +64 −20 web/mids/mids.go
  200. +17 −0 web/protoc-gen-browser/README.md
  201. +1,065 −0 web/protoc-gen-browser/browser.go
  202. +110 −0 web/protoc-gen-browser/main.go
  203. +184 −0 web/protoc-gen-browser/test/test.proto
  204. +1 −1 web/protoc-gen-go-web/README.md
  205. +56 −19 web/protoc-gen-go-web/main.go
  206. +155 −150 web/protoc-gen-go-web/test/test.proto
  207. +955 −321 web/protoc-gen-go-web/web.go
  208. +16 −0 web/protoc-gen-markdown/README.md
  209. +109 −0 web/protoc-gen-markdown/main.go
  210. +1,664 −0 web/protoc-gen-markdown/markdown.go
  211. +184 −0 web/protoc-gen-markdown/test/test.proto
  212. +590 −0 web/router.go
  213. +231 −492 web/server.go
  214. +27 −0 web/server_for_pick.go
  215. +76 −0 ws/client_test.go
  216. +51 −0 ws/const.go
  217. +160 −0 ws/cupgrader.go
  218. +154 −0 ws/reader.go
  219. +65 −0 ws/server_test.go
  220. +147 −0 ws/supgrader.go
  221. +28 −0 ws/test.html
  222. +125 −0 ws/writer.go
141 changes: 140 additions & 1 deletion Corelib.drawio
Original file line number Diff line number Diff line change
@@ -1 +1,140 @@
<mxfile host="app.diagrams.net" modified="2022-04-10T05:41:18.686Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36" etag="BmTLQ0dN-0NVyNT4E-Ye" version="17.4.2" type="device"><diagram id="rUxL1oKWxs3ilogCRd9T" name="Page-1">7Vxtd6I4FP41nrP7oR5eBO3H1tbunmlPu+s505mPFCJki8QJsdr59ZtAkJdERVDAGf3QwoUE8jz33tx7E+3p4/n6AVsL7wk5wO9pirPu6Xc9jX4G1/Qfk3zGkuH1IBa4GDqxSE0FU/gTcKHCpUvogDB3I0HIJ3CRF9ooCIBNcjILY7TK3zZDfv6pC8sFgmBqW74ofYUO8WLpSBum8r8AdL3kyarJBzy3kpv5SELPctAqI9Lve/oYI0Tio/l6DHwGXoJL3G6y5ermxTAISJkG40B7mECXvuEP8PwYPL64L+EV7+XD8pd8wE8ocJHz1tNMn3Z7+4bpkcuO/pgvQ8L6C+gfDBY+tK0QMMmcsv4nHyT5TJDDaBk4gD1cpa1XHiRgurBsdnVFdYXKPDL3+WVxMMmbAUzAOiPig3sAaA4I/qS38Ku6yYHmmmYY/HyV8qYmZHgZzpJ2FlcVd9N1iiY94IAeAK42EEABDtUufoow8ZCLAsu/T6W3KWwKPUvveURowcH6DxDyyU3FWhKUhxKsIfnGmvcNfvY9c+VuzXuOTj6Tk4CON9OInX7PXkubRWdJuxkKyBj5CEej0ycThX6oPCQYvYPMFUXhV7YSHaIltsEONHVu/RZ2Admv0gzpnWqDgW8R+JG386PrgC4YGPVUM+h2zlwGrZuLKUB1BzH16VPnXUCLDpLkIbF86Ab02KaQAKp1twwK6qL8G35hDh0ntjAQwp/WW9QVU8kFggGJBmPc9ow71hc1qjC2L1XQ5gAFrJcZ9P2C6BisGAUnpoqsDCWkaCfzYUa7PmxYxYnlXFjq0eo6sc2V6k5sWNKJ6Z1yYtqoXSXQOqQETD6ZNKIErc1kq/nXyf3Dl1cye/7mfvGevCn4+6pdR5BRgIw+7NEBNa8D2j4lkOJ9NI6lqA7apLTlADXH6bAkp/XsehOH7otQG1WC2oYdNb3B2PrM3MDjmrTnFyZIYw1Vzcca+rWR1ai995umUtDA+A1SfdwMpfrUMxSCQjEzFSVvyxAGIAwZSQB/QMqSpty0HnOrhZhbbz3m1szzm9nVWh7gpOHd6DzDu+H5xfinUoIjhHdllaBb4V2rOqD2qoR3hVCgyfBOwrEUVbPV8E7rDqdlw7t6dt1seFdWCdoJ74b6YeFd8f5GwrvR8cK729bDO6Nz4Z0qlp8TNJnl9Ni6WWIi5o8liuHWZ7PIWDKiGPdpDHZUkFVeLWJ7SW/07eIOE8p+k3qtVqjXDiT12k3e1EjBVhXL6GUoZ4TPZiLlmRL87820WYLpRivz6vbU+EJ0nSRd6xrR2yfJXUTb9CNz4s//njXDkohvd752gDNXjL3M640yf31hvhHmza4xn6Rul8DtRF5+MOpa4Ka3mq23sFuodLJeJTfXuOvsbilWXipoVQd62YpN2SLcYTog4Xo8PnZhRka+FO5Rm1zrbXKtHsB1tzhTlYZI2/maFbIu2cQcuDBYs2cGLo4KWuVm5YMqW9vWPo4wixY3EWqjtiteuiqA1dFZtMnZMIld986GiXp3ZGUyee+MtS1DGnQe0x72w1vdHtT27WEgIHizpK9C/ZQH7DPZWHtKxoplPb25as/2DWH5XdCSFZCxRekTxU//iLJ+v1/PXrZAKgF+R2UlB7IuAdk8kVVsX5b91UAeFpef2kZZrFuuwFvrMKlmvtaz8dkZmAZNWrwqTnJdwMnUu4aT+GU1vLBbx0nrHE5i7bALOBmdsztDwEkACQTODfsWKYt/fCsMoR2FLRYmojgDVz6hqJJzV93vLM3Vx+PKufpOS9yfq2tylchQbkgoT2SHbZARdrTohRrv5jzpIh4ob5Vqk9DRoLiVRi90FAMhdFRhl4wcxqpr+vJ1ILRkgTxtZLFHn/06QC2vVFwH0K7LBU2n80pVl/UvXO/N9ZSucV1tZZ9xbdsi1zAIfg2uhXw/V26uF60V5wTJHr1mdaBqQfmiA5UjUaVjOqCJmU2dRYX3UShWKGyE2S5ZJ2hkkaEQddZz24W6himpa5ysqCrnS8wc1L7PFgv4z6OwJZ0Q2Chw2B5lgkQ6lgvHIhEhMLTRB7PZ4i1an/+oDUSsTx9FP79CMHRld0s6PEszz5V2a+nNVSFqH2gSvZFlnKfTGzGOv+hN5/Sm+EWIU+oNPU1/ASpOF9Pf0dLv/wc=</diagram></mxfile>
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0" version="24.7.16">
<diagram id="rUxL1oKWxs3ilogCRd9T" name="Page-1">
<mxGraphModel dx="2015" dy="658" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="Cn2GFig116qeOLnLPgPs-1" value="Mongodb&lt;br&gt;(must in replicaset mode)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="360" y="585" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-24" value="&lt;span style=&quot;caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: center; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(251, 251, 251); text-decoration: none; float: none; display: inline !important;&quot;&gt;DirectSdk&lt;/span&gt;&lt;br style=&quot;border-color: var(--border-color); caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: center; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;&quot;&gt;&lt;span style=&quot;caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: center; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(251, 251, 251); text-decoration: none; float: none; display: inline !important;&quot;&gt;Watch&lt;/span&gt;" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontColor=#FF0000;strokeColor=#FF0000;" parent="1" source="Cn2GFig116qeOLnLPgPs-3" target="Cn2GFig116qeOLnLPgPs-1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-3" value="&lt;br&gt;&lt;br&gt;admin Service&lt;br&gt;(user/role/permission)&lt;br&gt;(app/remote config)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="360" y="460" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontColor=#FF0000;strokeColor=#FF0000;" parent="1" source="Cn2GFig116qeOLnLPgPs-7" target="Cn2GFig116qeOLnLPgPs-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;" parent="1" source="Cn2GFig116qeOLnLPgPs-7" target="wmVFEGKWtfOXgKhMhSeI-4" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.75;exitDx=0;exitDy=0;fontColor=#000000;strokeColor=#000000;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="Cn2GFig116qeOLnLPgPs-7" target="wmVFEGKWtfOXgKhMhSeI-21" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="110" y="395" />
<mxPoint x="110" y="695" />
</Array>
<mxPoint x="300" y="690" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-7" value="&lt;br&gt;&lt;br&gt;business service A" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="160" y="350" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-26" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontColor=#FF0000;strokeColor=#FF0000;" parent="1" source="Cn2GFig116qeOLnLPgPs-8" target="Cn2GFig116qeOLnLPgPs-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" parent="1" source="Cn2GFig116qeOLnLPgPs-8" target="wmVFEGKWtfOXgKhMhSeI-6" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontColor=#000000;strokeColor=#000000;" parent="1" source="Cn2GFig116qeOLnLPgPs-8" target="wmVFEGKWtfOXgKhMhSeI-21" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="730" y="395" />
<mxPoint x="730" y="695" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-8" value="&lt;br&gt;&lt;br&gt;business service B" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="560" y="350" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-13" value="&lt;font color=&quot;#ff0000&quot;&gt;ConfigSdk&lt;br&gt;Watch&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="145" y="410" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-22" value="&lt;font color=&quot;#ff0000&quot;&gt;ConfigSdk&lt;br&gt;Watch&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="615" y="410" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-32" value="&lt;span style=&quot;caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: center; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(251, 251, 251); text-decoration: none; float: none; display: inline !important;&quot;&gt;&lt;font color=&quot;#ffb570&quot;&gt;manager call&lt;br&gt;need&lt;br&gt;auth check&lt;br&gt;permission check&lt;br&gt;&lt;/font&gt;&lt;/span&gt;" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontColor=#000000;strokeColor=#FFB570;" parent="1" source="Cn2GFig116qeOLnLPgPs-29" target="Cn2GFig116qeOLnLPgPs-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#00CC00;" parent="1" source="Cn2GFig116qeOLnLPgPs-29" target="wmVFEGKWtfOXgKhMhSeI-8" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#00CC00;" parent="1" source="Cn2GFig116qeOLnLPgPs-29" target="wmVFEGKWtfOXgKhMhSeI-10" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-29" value="&lt;font color=&quot;#000000&quot;&gt;nginx ingress&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#FF0000;" parent="1" vertex="1">
<mxGeometry x="360" y="280" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-31" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;fontColor=#000000;strokeColor=#00CC00;entryX=0.25;entryY=0;entryDx=0;entryDy=0;" parent="1" source="Cn2GFig116qeOLnLPgPs-30" target="Cn2GFig116qeOLnLPgPs-29" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Cn2GFig116qeOLnLPgPs-30" value="&lt;font color=&quot;#00cc00&quot;&gt;user&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#000000;strokeColor=#00CC00;" parent="1" vertex="1">
<mxGeometry x="260" y="180" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-4" value="DB&lt;br&gt;Cache&lt;br&gt;MQ&lt;br&gt;..." style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="20" y="330" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-6" value="DB&lt;br&gt;Cache&lt;br&gt;MQ&lt;br&gt;..." style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="760" y="330" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-8" value="web" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="165" y="360" width="40" height="20" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-10" value="web" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="635" y="360" width="40" height="20" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-11" value="rpc" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="235" y="360" width="40" height="20" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-12" value="rpc" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="565" y="360" width="40" height="20" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-15" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;strokeColor=#00CCCC;" parent="1" source="wmVFEGKWtfOXgKhMhSeI-11" target="wmVFEGKWtfOXgKhMhSeI-12" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="380" y="380" as="sourcePoint" />
<mxPoint x="430" y="330" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-16" value="&lt;font color=&quot;#00cc00&quot;&gt;user outer call&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="480" y="280" width="100" height="30" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-17" value="&lt;font color=&quot;#00cc00&quot;&gt;user outer call&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="250" y="280" width="100" height="30" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-18" value="&lt;font color=&quot;#00cccc&quot;&gt;inner call&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#00CC00;" parent="1" vertex="1">
<mxGeometry x="280" y="340" width="60" height="20" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-19" value="&lt;font color=&quot;#00cccc&quot;&gt;inner call&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#00CC00;" parent="1" vertex="1">
<mxGeometry x="500" y="340" width="60" height="20" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-21" value="&lt;font color=&quot;#000000&quot;&gt;dicover:&lt;/font&gt;&lt;div&gt;&lt;font color=&quot;#000000&quot;&gt;1.static addr&lt;br&gt;&lt;/font&gt;&lt;div&gt;&lt;font color=&quot;#000000&quot;&gt;2.k8s api server&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color=&quot;#000000&quot;&gt;3.dns&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontColor=#00CCCC;" parent="1" vertex="1">
<mxGeometry x="360" y="650" width="120" height="90" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-25" value="1.loop in x seconds to&lt;br&gt;update discover&lt;br&gt;2.connection lost triger&lt;br&gt;update discover" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#000000;" parent="1" vertex="1">
<mxGeometry x="-30" y="420" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="wmVFEGKWtfOXgKhMhSeI-26" value="1.loop in x seconds to&lt;br&gt;update discover&lt;br&gt;2.connection lost triger&lt;br&gt;update discover" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#000000;" parent="1" vertex="1">
<mxGeometry x="730" y="420" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="OUvODyNElc9ULqvnpfPR-2" value="&lt;font color=&quot;#ffb570&quot;&gt;proxy call&lt;/font&gt;" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeColor=#FFB570;" parent="1" source="Cn2GFig116qeOLnLPgPs-3" target="wmVFEGKWtfOXgKhMhSeI-12" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="OUvODyNElc9ULqvnpfPR-3" value="&lt;font color=&quot;#ffb570&quot;&gt;proxy call&lt;/font&gt;" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;strokeColor=#FFB570;" parent="1" source="Cn2GFig116qeOLnLPgPs-3" target="wmVFEGKWtfOXgKhMhSeI-11" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="OUvODyNElc9ULqvnpfPR-7" value="web" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="400" y="460" width="40" height="20" as="geometry" />
</mxCell>
<mxCell id="OUvODyNElc9ULqvnpfPR-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;strokeColor=#FFB570;" parent="1" source="OUvODyNElc9ULqvnpfPR-8" target="Cn2GFig116qeOLnLPgPs-29" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="OUvODyNElc9ULqvnpfPR-8" value="&lt;font color=&quot;#ffb570&quot;&gt;manager&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;strokeColor=#FFB570;" parent="1" vertex="1">
<mxGeometry x="460" y="180" width="120" height="60" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
Binary file modified Corelib.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 22 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
# Corelib
![image](Corelib.jpg)
# Use
1.install golang(1.18+)
1.install golang(1.24.1+)
2.install git
3.install protoc
4.install protoc-gen-go
5.[download the codegen in release] or [clone this lib and go into the codegen dir and install it by go install]
6.make sure the codegen's dir is in the system's or user's PATH env
7.codegen -d path -n projectname -p packagename
(without -d or -d is empty the default value: current dir will be used)
(projectname format,character must in [a-z][A-Z][0-9][_],first character must in [a-z][A-Z])
(packagename must end with projectname,default projectname will be used as packagename,e.g. github.com/path_to_the_repo/projectname)
5.[download the codegen in release] or [clone this repo and go into the codegen dir and install it by go install]
6.make sure the codegen's path is in the system's or user's PATH env
7.use this command to generate the base code:codegen -n projectname -p packagename
(projectname format:character must in [a-z][0-9],first character must in [a-z])
(packagename format:must end with projectname,default:projectname,e.g. github.com/path_to_the_repo/projectname)
# Description
## codegen
generate the base code,if you want to use this lib,this is the start
## web
Web framework,this contains protobuf plugin to generate code from proto file
Web framework contains trace and metrics function from opentelemetry,this also contains protobuf plugin to generate code from proto file
## cgrpc
grpc framework,this contains protobuf plugin to generate code from proto file
grpc framework contains trace and metrics function from opentelemetry,this also contains protobuf plugin to generate code from proto file
## crpc
a new rpc framework contains trace and metrics function from opentelemetry,this also contains protobuf plugin to generate code from proto file
## pbex
protobuf extension for message validate,this is used in the web/crpc/cgrpc framework
## stream
stream connection framework,use websocket's frame format,so this can support rawtcp and websocket at the same time on same port
## crpc
a new rpc framework(20-30% fast then grpc),this contains protobuf plugin to generate code from proto file
## id
snow flake
## log
normal log
## trace
trace log
## pool
sync.Pool for []byte and bufio.Reader and bufio.Writer
## ws
a simple ws handshake and message recv and send framework
## container
some useful struct
## mysql
mysql driver wrapper with trace support and read write seprate
## mongo
mongodb driver wrapper with trace support
## redis
redis driver wrapper with trace support and some useful function(bloom filter,rate limiter,message queue,verify code check)
## email
simple email client used to send email
## superd
fork child process to exec some other program,like supervisor
## other
1.remote config center
https://github.com/chenjie199234/config
115 changes: 115 additions & 0 deletions cerror/cerror.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package cerror

import (
"context"
"encoding/json"
"log/slog"
"net/http"
"strconv"
"strings"

"github.com/chenjie199234/Corelib/util/common"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/encoding/protojson"
)

func MakeCError(code int32, httpcode int32, msg string) *Error {
if code == 0 {
panic("error code can't be 0")
}
if httpcode < 400 {
panic("error's http code must >= 400")
}
if http.StatusText(int(httpcode)) == "" {
panic("error's http code unknown")
}
return &Error{
Code: code,
Httpcode: httpcode,
Msg: msg,
}
}
func (this *Error) Error() string {
return "code=" + strconv.FormatInt(int64(this.Code), 10) + ",msg=" + this.Msg
}
func (this *Error) Json() string {
d, _ := json.Marshal(this.Msg)
return "{\"code\":" + strconv.FormatInt(int64(this.Code), 10) + ",\"msg\":" + common.BTS(d) + "}"
}
func (this *Error) GRPCStatus() *status.Status {
return status.New(codes.Code(this.Httpcode), this.Error())
}
func (this *Error) SlogAttr() *slog.Attr {
return &slog.Attr{Key: "error", Value: slog.GroupValue(slog.Int64("code", int64(this.Code)), slog.String("msg", this.Msg))}
}
func (this *Error) SetHttpcode(httpcode int32) {
this.Httpcode = httpcode
}
func Equal(a, b error) bool {
aa := Convert(a)
bb := Convert(b)
if aa == nil && bb == nil {
return true
} else if (aa == nil && bb != nil) || (aa != nil && bb == nil) {
return false
}
return aa.Code == bb.Code && aa.Msg == bb.Msg
}
func Convert(e error) *Error {
if e == nil {
return nil
}
if e == context.DeadlineExceeded {
return ErrDeadlineExceeded
} else if e == context.Canceled {
return ErrCanceled
}
result, ok := e.(*Error)
if ok {
return result
}
return MakeCError(-1, 500, e.Error())
}
func Decode(estr string) *Error {
if estr == "" {
return nil
}
if estr == ErrDeadlineExceeded.Json() || estr == ErrDeadlineExceeded.Error() {
return ErrDeadlineExceeded
} else if estr == ErrCanceled.Json() || estr == ErrCanceled.Error() {
return ErrCanceled
}
if estr[0] == '{' && estr[len(estr)-1] == '}' {
//json format
tmp := &Error{}
//protojson can support "number string" or "number" for field:code
if e := (protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}).Unmarshal(common.STB(estr), tmp); e != nil {
return MakeCError(-1, 500, estr)
}
if tmp.Code == 0 {
return nil
}
if tmp.Httpcode == 0 {
tmp.Httpcode = 500
}
return tmp
} else {
//text format
index := strings.Index(estr, ",")
if index == -1 {
return MakeCError(-1, 500, estr)
}
p1 := estr[:index]
p2 := estr[index+1:]
if !strings.HasPrefix(p1, "code=") || !strings.HasPrefix(p2, "msg=") {
return MakeCError(-1, 500, estr)
}
code, e := strconv.ParseInt(p1[5:], 10, 32)
if e != nil {
return MakeCError(-1, 500, estr)
}
msg := p2[4:]
return MakeCError(int32(code), 500, msg)
}
}
146 changes: 146 additions & 0 deletions cerror/cerror.pb.go
8 changes: 8 additions & 0 deletions cerror/cerror.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
syntax="proto3";
package cerror;
option go_package="github.com/chenjie199234/Corelib/cerror;cerror";
message Error{
int32 code=1;
int32 httpcode=2;
string msg=3;
}
61 changes: 61 additions & 0 deletions cerror/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package cerror

import (
"context"
"net/http"
)

// system,start from 1000
var (
ErrServerClosing = MakeCError(1000, http.StatusServiceUnavailable, "server is closing")
ErrClientClosing = MakeCError(1001, http.StatusBadRequest, "using closed client")
ErrTarget = MakeCError(1002, http.StatusBadRequest, "wrong server,check the server group and name")
ErrNoapi = MakeCError(1003, http.StatusNotImplemented, "api not implement")
ErrPanic = MakeCError(1004, http.StatusServiceUnavailable, "panic")
ErrNoserver = MakeCError(1005, http.StatusServiceUnavailable, "no servers")
ErrNoSpecificserver = MakeCError(1006, http.StatusServiceUnavailable, "no specific server")
ErrDiscoverStopped = MakeCError(1007, http.StatusBadRequest, "discover stopped")
ErrClosed = MakeCError(1008, http.StatusInternalServerError, "connection closed")
ErrReqmsgLen = MakeCError(1009, http.StatusBadRequest, "req msg too large")
ErrRespmsgLen = MakeCError(1010, http.StatusInternalServerError, "resp msg too large")

ErrCors = MakeCError(2001, http.StatusForbidden, "Cors forbidden")
)
var (
ErrDataConflict = MakeCError(9001, http.StatusInternalServerError, "data conflict")
ErrDataBroken = MakeCError(9002, http.StatusInternalServerError, "data broken")

ErrDBDataConflict = MakeCError(9101, http.StatusInternalServerError, "db data conflict")
ErrDBDataBroken = MakeCError(9102, http.StatusInternalServerError, "db data broken")

ErrCacheDataConflict = MakeCError(9201, http.StatusInternalServerError, "cache data conflict")
ErrCacheDataBroken = MakeCError(9202, http.StatusInternalServerError, "cache data broken")

ErrMQDataBroken = MakeCError(9301, http.StatusInternalServerError, "message queue data broken")
)

// business,start from 10000
var (
ErrUnknown = MakeCError(10000, http.StatusInternalServerError, "unknown")
ErrReq = MakeCError(10001, http.StatusBadRequest, "request error")
ErrResp = MakeCError(10002, http.StatusInternalServerError, "response error")
ErrSystem = MakeCError(10003, http.StatusInternalServerError, "system error")
ErrToken = MakeCError(10004, http.StatusUnauthorized, "token wrong")
ErrSession = MakeCError(10005, http.StatusUnauthorized, "session wrong")
ErrAccessKey = MakeCError(10006, http.StatusUnauthorized, "access key wrong")
ErrAccessSign = MakeCError(10007, http.StatusUnauthorized, "access sign wrong")
ErrPermission = MakeCError(10008, http.StatusForbidden, "permission denie")
ErrTooFast = MakeCError(10009, http.StatusForbidden, "too fast")
ErrBan = MakeCError(10010, http.StatusForbidden, "ban")
ErrBusy = MakeCError(10011, http.StatusServiceUnavailable, "busy")
ErrNotExist = MakeCError(10012, http.StatusNotFound, "not exist")
ErrAlreadyExist = MakeCError(10013, http.StatusBadRequest, "already exist")
ErrPasswordWrong = MakeCError(10014, http.StatusBadRequest, "password wrong")
ErrPasswordLength = MakeCError(10015, http.StatusBadRequest, "password length must <=32")
)

// convert std error,always -1
var (
ErrDeadlineExceeded = MakeCError(-1, http.StatusGatewayTimeout, context.DeadlineExceeded.Error())
ErrCanceled = MakeCError(-1, http.StatusRequestTimeout, context.Canceled.Error())
)
448 changes: 295 additions & 153 deletions cgrpc/balancer.go

Large diffs are not rendered by default.

389 changes: 235 additions & 154 deletions cgrpc/client.go

Large diffs are not rendered by default.

146 changes: 146 additions & 0 deletions cgrpc/clientcontext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package cgrpc

import (
"io"
"log/slog"

"github.com/chenjie199234/Corelib/cerror"
"github.com/chenjie199234/Corelib/pbex"

"google.golang.org/grpc"
"google.golang.org/grpc/peer"
)

// ----------------------------------------------- client stream context ---------------------------------------------
func NewClientStreamClientContext[reqtype any](path string, stream grpc.ClientStream, validatereq bool) *ClientStreamClientContext[reqtype] {
return &ClientStreamClientContext[reqtype]{
validatereq: validatereq,
path: path,
stream: stream,
}
}

type ClientStreamClientContext[reqtype any] struct {
validatereq bool
path string
stream grpc.ClientStream
}

func (c *ClientStreamClientContext[reqtype]) GetPath() string {
return c.path
}

// Send will not wait peer to confirm accept the message,so there may be data lost if peer closed and self send at the same time
func (c *ClientStreamClientContext[reqtype]) Send(req *reqtype) error {
var tmp any = req
if c.validatereq {
if v, ok := tmp.(pbex.Validater); ok {
if errstr := v.Validate(); errstr != "" {
slog.ErrorContext(c.stream.Context(), "["+c.path+"] request validate failed", slog.String("error", errstr))
return cerror.ErrReq
}
}
}
e := c.stream.SendMsg(req)
if e != nil && e != io.EOF {
slog.ErrorContext(c.stream.Context(), "["+c.path+"] send request failed", slog.String("error", e.Error()))
}
return e
}
func (c *ClientStreamClientContext[reqtype]) GetServerAddr() string {
p, ok := peer.FromContext(c.stream.Context())
if !ok {
return ""
}
return p.Addr.String()
}

// ----------------------------------------------- server stream context ---------------------------------------------
func NewServerStreamClientContext[resptype any](path string, stream grpc.ClientStream) *ServerStreamClientContext[resptype] {
return &ServerStreamClientContext[resptype]{
path: path,
stream: stream,
}
}

type ServerStreamClientContext[resptype any] struct {
path string
stream grpc.ClientStream
}

func (c *ServerStreamClientContext[resptype]) GetPath() string {
return c.path
}

func (c *ServerStreamClientContext[resptype]) Recv() (*resptype, error) {
resp := new(resptype)
if e := c.stream.RecvMsg(resp); e != nil {
if e != io.EOF {
slog.ErrorContext(c.stream.Context(), "["+c.path+"] read response failed", slog.String("error", e.Error()))
}
return nil, e
}
return resp, nil
}
func (c *ServerStreamClientContext[resptype]) GetServerAddr() string {
p, ok := peer.FromContext(c.stream.Context())
if !ok {
return ""
}
return p.Addr.String()
}

// ----------------------------------------------- all stream context ---------------------------------------------
func NewAllStreamClientContext[reqtype, resptype any](path string, stream grpc.ClientStream, validatereq bool) *AllStreamClientContext[reqtype, resptype] {
return &AllStreamClientContext[reqtype, resptype]{
path: path,
validatereq: validatereq,
stream: stream,
}
}

type AllStreamClientContext[reqtype, resptype any] struct {
path string
validatereq bool
stream grpc.ClientStream
}

func (c *AllStreamClientContext[reqtype, resptype]) GetPath() string {
return c.path
}

func (c *AllStreamClientContext[reqtype, resptype]) Recv() (*resptype, error) {
resp := new(resptype)
if e := c.stream.RecvMsg(resp); e != nil {
if e != io.EOF {
slog.ErrorContext(c.stream.Context(), "["+c.path+"] read response failed", slog.String("error", e.Error()))
}
return nil, e
}
return resp, nil
}

// Send will not wait peer to confirm accept the message,so there may be data lost if peer closed and self send at the same time
func (c *AllStreamClientContext[reqtype, resptype]) Send(req *reqtype) error {
var tmp any = req
if c.validatereq {
if v, ok := tmp.(pbex.Validater); ok {
if errstr := v.Validate(); errstr != "" {
slog.ErrorContext(c.stream.Context(), "["+c.path+"] request validate failed", slog.String("error", errstr))
return cerror.ErrReq
}
}
}
e := c.stream.SendMsg(req)
if e != nil && e != io.EOF {
slog.ErrorContext(c.stream.Context(), "["+c.path+"] send request failed", slog.String("error", e.Error()))
}
return e
}
func (c *AllStreamClientContext[reqtype, resptype]) GetServerAddr() string {
p, ok := peer.FromContext(c.stream.Context())
if !ok {
return ""
}
return p.Addr.String()
}
104 changes: 0 additions & 104 deletions cgrpc/context.go

This file was deleted.

89 changes: 89 additions & 0 deletions cgrpc/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package cgrpc

import (
"io"
"net/http"
"strings"

"github.com/chenjie199234/Corelib/cerror"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

// Warning!this function is only used for generated code,don't use it in any other place
// clientorserver:
// -- client true
// -- server false
func transGrpcError(e error, clientorserver bool) error {
if e == io.EOF {
return e
}
if ee, ok := e.(*cerror.Error); ok {
return ee
}
s := status.Convert(e)
if s == nil {
return nil
}
switch s.Code() {
case codes.OK:
return nil
case codes.Canceled:
if strings.Contains(s.Message(), "is closing") {
return cerror.ErrClosed
}
return cerror.ErrCanceled
case codes.DeadlineExceeded:
return cerror.ErrDeadlineExceeded
case codes.Unknown:
return cerror.Decode(s.Message())
case codes.InvalidArgument:
return cerror.ErrReq
case codes.NotFound:
return cerror.ErrNotExist
case codes.AlreadyExists:
return cerror.ErrAlreadyExist
case codes.PermissionDenied:
return cerror.ErrPermission
case codes.ResourceExhausted:
if strings.Contains(s.Message(), "received message") && strings.Contains(s.Message(), "larger") {
if clientorserver {
return cerror.ErrRespmsgLen
}
return cerror.ErrReqmsgLen
} else if (strings.Contains(s.Message(), "send message") && strings.Contains(s.Message(), "larger")) || strings.Contains(s.Message(), "message too large") {
if clientorserver {
return cerror.ErrReqmsgLen
}
return cerror.ErrRespmsgLen
}
return cerror.MakeCError(-1, http.StatusInternalServerError, s.Message())
case codes.FailedPrecondition:
return cerror.MakeCError(-1, http.StatusInternalServerError, s.Message())
case codes.Aborted:
return cerror.MakeCError(-1, http.StatusInternalServerError, s.Message())
case codes.OutOfRange:
return cerror.MakeCError(-1, http.StatusInternalServerError, s.Message())
case codes.Unimplemented:
return cerror.ErrNoapi
case codes.Internal:
return cerror.MakeCError(-1, http.StatusInternalServerError, s.Message())
case codes.Unavailable:
if strings.Contains(s.Message(), "EOF") {
return io.EOF
} else if strings.Contains(s.Message(), "is closing") ||
(strings.Contains(s.Message(), "connection") && strings.Contains(s.Message(), "closed")) {
return cerror.ErrClosed
}
return cerror.MakeCError(-1, http.StatusServiceUnavailable, s.Message())
case codes.DataLoss:
return cerror.MakeCError(-1, http.StatusNotFound, s.Message())
case codes.Unauthenticated:
return cerror.MakeCError(-1, http.StatusInternalServerError, s.Message())
default:
ee := cerror.Decode(s.Message())
ee.SetHttpcode(int32(s.Code()))
return ee
}
}
59 changes: 48 additions & 11 deletions cgrpc/mids/mids.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,79 @@
package mids

import (
"github.com/chenjie199234/Corelib/cerror"
"github.com/chenjie199234/Corelib/cgrpc"
cerror "github.com/chenjie199234/Corelib/error"
"github.com/chenjie199234/Corelib/metadata"
publicmids "github.com/chenjie199234/Corelib/mids"
)

//dosn't include global mids in here
// dosn't include global mids in here
var all map[string]cgrpc.OutsideHandler

func init() {
all = make(map[string]cgrpc.OutsideHandler)
//register here
all["rate"] = rate
all["token"] = token
all["session"] = session
all["accesskey"] = accesskey
}

func AllMids() map[string]cgrpc.OutsideHandler {
return all
}

//thread unsafe
// thread unsafe
func RegMid(name string, handler cgrpc.OutsideHandler) {
all[name] = handler
}
func rate(ctx *cgrpc.Context) {
if !publicmids.GrpcRate(ctx.GetPath()) {
ctx.Abort(cerror.ErrLimit)
func rate(ctx *cgrpc.ServerContext) {
if pass := publicmids.GrpcRate(ctx, ctx.GetPath()); !pass {
ctx.Abort(cerror.ErrBusy)
}
}
func accesskey(ctx *cgrpc.Context) {
md := ctx.GetMetadata()
func token(ctx *cgrpc.ServerContext) {
md := metadata.GetMetadata(ctx)
tokenstr := md["Token"]
if tokenstr == "" {
ctx.Abort(cerror.ErrToken)
return
}
t := publicmids.VerifyToken(ctx, tokenstr)
if t == nil {
ctx.Abort(cerror.ErrToken)
return
}
md["Token-DeployEnv"] = t.DeployEnv
md["Token-RunEnv"] = t.RunEnv
md["Token-Puber"] = t.Puber
md["Token-User"] = t.UserID
md["Token-Data"] = t.Data
}
func session(ctx *cgrpc.ServerContext) {
md := metadata.GetMetadata(ctx)
sessionstr := md["Session"]
if sessionstr == "" {
ctx.Abort(cerror.ErrSession)
return
}
userid, sessiondata, pass := publicmids.VerifySession(ctx, sessionstr)
if !pass {
ctx.Abort(cerror.ErrSession)
return
}
md["Session-User"] = userid
md["Session-Data"] = sessiondata
}
func accesskey(ctx *cgrpc.ServerContext) {
md := metadata.GetMetadata(ctx)
accesskey := md["Access-Key"]
if accesskey == "" {
ctx.Abort(cerror.ErrAuth)
ctx.Abort(cerror.ErrAccessKey)
return
}
if !publicmids.AccessKey(ctx.GetPath(), accesskey) {
ctx.Abort(cerror.ErrAuth)
delete(md, "Access-Key")
if !publicmids.VerifyAccessKey(ctx, "GRPC", ctx.GetPath(), accesskey) {
ctx.Abort(cerror.ErrAccessKey)
}
}
97 changes: 0 additions & 97 deletions cgrpc/picker.go

This file was deleted.

452 changes: 383 additions & 69 deletions cgrpc/protoc-gen-go-cgrpc/cgrpc.go

Large diffs are not rendered by default.

51 changes: 37 additions & 14 deletions cgrpc/protoc-gen-go-cgrpc/main.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,68 @@
package main

import (
"flag"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/chenjie199234/Corelib/internal/version"
"github.com/chenjie199234/Corelib/pbex"

"google.golang.org/protobuf/compiler/protogen"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/descriptorpb"
"google.golang.org/protobuf/types/pluginpb"
)

var version = "v0.0.1"

func main() {
if len(os.Args) == 2 && os.Args[1] == "--version" {
fmt.Fprintf(os.Stderr, "%v %v\n", filepath.Base(os.Args[0]), version)
os.Exit(0)
ver := flag.Bool("v", false, "version info")
flag.Parse()
if *ver {
fmt.Println(version.String())
return
}
protogen.Options{}.Run(func(gen *protogen.Plugin) error {
//pre check
needfile := make(map[string]bool)
for _, f := range gen.Files {
if !f.Generate {
continue
}
if *f.Proto.Syntax != "proto3" {
panic("this plugin only support proto3 syntax!")
panic("plugin only support proto3 syntax!")
}
for _, m := range f.Messages {
if pbex.OneOfHasPBEX(m) {
panic("oneof fields should not contain pbex")
}
}
for _, s := range f.Services {
if s.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() {
continue
}
for _, m := range s.Methods {
if m.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() {
mop := m.Desc.Options().(*descriptorpb.MethodOptions)
if mop.GetDeprecated() || !proto.HasExtension(mop, pbex.E_Method) {
continue
}
if pbex.HasOneOf(m.Input) || pbex.HasOneOf(m.Output) {
panic("can't support oneof in proto!")
emethod := proto.GetExtension(mop, pbex.E_Method).([]string)
need := false
for _, em := range emethod {
if strings.ToUpper(em) == "GRPC" {
need = true
break
}
}
if !need {
continue
}
needfile[f.Desc.Path()] = true
if pbex.OneOfHasPBEX(m.Input) {
panic("oneof fields should not contain pbex")
}
if pbex.OneOfHasPBEX(m.Output) {
panic("oneof fields should not contain pbex")
}
}
}
@@ -48,10 +74,7 @@ func main() {
}
//gen file
for _, f := range gen.Files {
if !f.Generate {
continue
}
if f.Desc.Options().(*descriptorpb.FileOptions).GetDeprecated() {
if status, ok := needfile[f.Desc.Path()]; !ok || !status {
continue
}
generateFile(gen, f)
199 changes: 32 additions & 167 deletions cgrpc/protoc-gen-go-cgrpc/test/test.proto
Original file line number Diff line number Diff line change
@@ -1,179 +1,44 @@
//protoc -I ../../../pbex -I . --go_out=paths=source_relative:. *.proto
//protoc -I ../../../pbex -I . --go-cgrpc_out=paths=source_relative:. *.proto
syntax="proto3";
package test;
option go_package="github.com/chenjie199234/Corelib/grpc/protoc-gen-go-grpc/test;test";
option go_package="github.com/chenjie199234/Corelib/web/protoc-gen-go-cgrpc/test;test";
import "pbex.proto";
service test {
rpc hello(helloreq)returns(helloresp){
option (pbex.method)="get";
option (pbex.grpc_midwares)="user";
option (pbex.grpc_midwares)="limit";
rpc call(callreq)returns(callresp){
option (pbex.method)="grpc";
option (pbex.cgrpc_midwares)="auth";
}
rpc clientstream(stream clientstreamreq)returns(clientstreamresp){
option (pbex.method)="grpc";
}
rpc serverstream(serverstreamreq)returns(stream serverstreamresp){
option (pbex.method)="grpc";
}
rpc allstream(stream allstreamreq)returns(stream allstreamresp){
option (pbex.method)="grpc";
}
}
message callreq{
uint64 u64=1[(pbex.uint_gt)=10];
}
message callresp{
bool status=1;
}
enum TestEnum {
ENUMA=0;
ENUMB=1;
message clientstreamreq{
uint64 u64=1[(pbex.uint_gt)=10];
}
message test_data{
int32 i32=1[(pbex.int_in)=1];
repeated int32 ri32=2[(pbex.int_not_in)=1];
uint32 ui32=3[(pbex.uint_in)=1];
repeated uint32 rui32=4[(pbex.map_repeated_len_gt)=2,(pbex.uint_not_in)=1];
int64 i64=5;
repeated int64 ri64=6;
uint64 ui64=7;
repeated uint64 rui64=8;
bytes bs=9;
repeated bytes rbs=10;
string ss=11;
repeated string rss=12[(pbex.string_bytes_reg_not_match)="123*"];
float f=13;
repeated float rf=14;
double d=15;
repeated double rd=16;
TestEnum e=17;
repeated TestEnum re=18;
test_data m=19;
repeated test_data rm=20;

map<int32,int32> mi32_i32=21;
map<int32,uint32> mi32_ui32=22;
map<int32,int64> mi32_i64=23;
map<int32,uint64> mi32_ui64=24;
map<int32,bytes> mi32_bs=25;
map<int32,string> mi32_ss=26;
map<int32,float> mi32_f=27;
map<int32,double> mi32_d=28;
map<int32,TestEnum> mi32_e=29;
map<int32,test_data> mi32_m=30;

map<uint32,int32> mui32_i32=31;
map<uint32,uint32> mui32_ui32=32;
map<uint32,int64> mui32_i64=33;
map<uint32,uint64> mui32_ui64=34;
map<uint32,bytes> mui32_bs=35;
map<uint32,string> mui32_ss=36[(pbex.map_value_string_bytes_reg_not_match)="789*"];
map<uint32,float> mui32_f=37;
map<uint32,double> mui32_d=38;
map<uint32,TestEnum> mui32_e=39;
map<uint32,test_data> mui32_m=40;

map<int64,int32> mi64_i32=41;
map<int64,uint32> mi64_ui32=42;
map<int64,int64> mi64_i64=43;
map<int64,uint64> mi64_ui64=44;
map<int64,bytes> mi64_bs=45;
map<int64,string> mi64_ss=46;
map<int64,float> mi64_f=47;
map<int64,double> mi64_d=48;
map<int64,TestEnum> mi64_e=49;
map<int64,test_data> mi64_m=50;

map<uint64,int32> mui64_i32=51;
map<uint64,uint32> mui64_ui32=52;
map<uint64,int64> mui64_i64=53;
map<uint64,uint64> mui64_ui64=54;
map<uint64,bytes> mui64_bs=55;
map<uint64,string> mui64_ss=56;
map<uint64,float> mui64_f=57;
map<uint64,double> mui64_d=58;
map<uint64,TestEnum> mui64_e=59;
map<uint64,test_data> mui64_m=60[(pbex.map_value_message_not_nil)=true];

map<string,int32> mss_i32=61[(pbex.map_key_string_reg_not_match)="notkey*"];
map<string,uint32> mss_ui32=62;
map<string,int64> mss_i64=63;
map<string,uint64> mss_ui64=64;
map<string,bytes> mss_bs=65;
map<string,string> mss_ss=66;
map<string,float> mss_f=67;
map<string,double> mss_d=68;
map<string,TestEnum> mss_e=69;
map<string,test_data> mss_m=70;
message clientstreamresp{
bool status=1;
}
message helloreq{
int32 i32=1[(pbex.int_in)=1];
repeated int32 ri32=2[(pbex.int_not_in)=1];
uint32 ui32=3[(pbex.uint_in)=1];
repeated uint32 rui32=4[(pbex.map_repeated_len_gt)=2,(pbex.uint_not_in)=1];
int64 i64=5;
repeated int64 ri64=6;
uint64 ui64=7;
repeated uint64 rui64=8;
bytes bs=9;
repeated bytes rbs=10;
string ss=11;
repeated string rss=12[(pbex.string_bytes_reg_match)="abc*"];
float f=13;
repeated float rf=14;
double d=15;
repeated double rd=16;
TestEnum e=17;
repeated TestEnum re=18;
test_data m=19[(pbex.message_not_nil)=true];
repeated test_data rm=20[(pbex.message_not_nil)=true];

map<int32,int32> mi32_i32=21;
map<int32,uint32> mi32_ui32=22;
map<int32,int64> mi32_i64=23;
map<int32,uint64> mi32_ui64=24;
map<int32,bytes> mi32_bs=25;
map<int32,string> mi32_ss=26;
map<int32,float> mi32_f=27;
map<int32,double> mi32_d=28;
map<int32,TestEnum> mi32_e=29;
map<int32,test_data> mi32_m=30;

map<uint32,int32> mui32_i32=31;
map<uint32,uint32> mui32_ui32=32;
map<uint32,int64> mui32_i64=33;
map<uint32,uint64> mui32_ui64=34;
map<uint32,bytes> mui32_bs=35;
map<uint32,string> mui32_ss=36[(pbex.map_value_string_bytes_reg_match)="xyz*"];
map<uint32,float> mui32_f=37;
map<uint32,double> mui32_d=38;
map<uint32,TestEnum> mui32_e=39;
map<uint32,test_data> mui32_m=40;

map<int64,int32> mi64_i32=41;
map<int64,uint32> mi64_ui32=42;
map<int64,int64> mi64_i64=43;
map<int64,uint64> mi64_ui64=44;
map<int64,bytes> mi64_bs=45;
map<int64,string> mi64_ss=46;
map<int64,float> mi64_f=47;
map<int64,double> mi64_d=48;
map<int64,TestEnum> mi64_e=49;
map<int64,test_data> mi64_m=50;

map<uint64,int32> mui64_i32=51;
map<uint64,uint32> mui64_ui32=52;
map<uint64,int64> mui64_i64=53;
map<uint64,uint64> mui64_ui64=54;
map<uint64,bytes> mui64_bs=55;
map<uint64,string> mui64_ss=56;
map<uint64,float> mui64_f=57;
map<uint64,double> mui64_d=58;
map<uint64,TestEnum> mui64_e=59;
map<uint64,test_data> mui64_m=60;

map<string,int32> mss_i32=61[(pbex.map_key_string_reg_match)="key*"];
map<string,uint32> mss_ui32=62;
map<string,int64> mss_i64=63;
map<string,uint64> mss_ui64=64;
map<string,bytes> mss_bs=65;
map<string,string> mss_ss=66;
map<string,float> mss_f=67;
map<string,double> mss_d=68;
map<string,TestEnum> mss_e=69;
map<string,test_data> mss_m=70;
message serverstreamreq{
uint64 u64=1[(pbex.uint_gt)=10];
}
message helloresp{

message serverstreamresp{
bool status=1;
}
message worldreq{

message allstreamreq{
uint64 u64=1[(pbex.uint_gt)=10];
}
message worldresp{

message allstreamresp{
bool status=1;
}
116 changes: 0 additions & 116 deletions cgrpc/resolver.go

This file was deleted.

497 changes: 348 additions & 149 deletions cgrpc/server.go

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions cgrpc/server_for_pick.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package cgrpc

import (
"sync/atomic"

"github.com/chenjie199234/Corelib/internal/picker"

"google.golang.org/grpc/balancer"
"google.golang.org/grpc/connectivity"
)

type ServerForPick struct {
addr string
subconn balancer.SubConn
dservers map[string]*struct{} //this app registered on which discovery server
status int32
closing atomic.Bool

Pickinfo *picker.ServerPickInfo
}

func (s *ServerForPick) GetServerPickInfo() *picker.ServerPickInfo {
return s.Pickinfo
}
func (s *ServerForPick) GetServerAddr() string {
return s.addr
}
func (s *ServerForPick) Pickable() bool {
return s.status == int32(connectivity.Ready) && !s.closing.Load()
}
290 changes: 290 additions & 0 deletions cgrpc/servercontext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
package cgrpc

import (
"context"
"io"
"log/slog"
"net/http"
"strconv"
"sync/atomic"

"github.com/chenjie199234/Corelib/cerror"
"github.com/chenjie199234/Corelib/metadata"
"github.com/chenjie199234/Corelib/pbex"

"google.golang.org/grpc"
"google.golang.org/grpc/stats"
)

type ServerContext struct {
context.Context
decodefunc func(any) error
stream grpc.ServerStream
path string
peerip string
resp any
e *cerror.Error
finish int32
}

func (c *ServerContext) Abort(e error) {
if atomic.SwapInt32(&c.finish, 1) != 0 {
return
}
httpcode := 0
if ee := cerror.Convert(e); ee != nil {
if http.StatusText(int(ee.Httpcode)) == "" || ee.Httpcode < 400 {
c.e = cerror.ErrPanic
httpcode = int(ee.Httpcode)
} else {
c.e = ee
}
}
if httpcode != 0 {
panic("[cgrpc.Context.Abort] unknown http code: " + strconv.Itoa(httpcode))
}
}

// Warning!this function is only used for generated code,don't use it in any other place
func (c *ServerContext) Read(req any) error {
if c.stream != nil {
return transGrpcError(c.stream.RecvMsg(req), false)
}
return transGrpcError(c.decodefunc(req), false)
}

// Warning!this function is only used for generated code,don't use it in any other place
func (c *ServerContext) Write(resp any) error {
if c.stream != nil {
return transGrpcError(c.stream.SendMsg(resp), false)
}
c.resp = resp
return nil
}
func (c *ServerContext) GetMethod() string {
return "GRPC"
}
func (c *ServerContext) GetPath() string {
return c.path
}

// get the direct peer's addr(maybe a proxy)
func (c *ServerContext) GetRemoteAddr() string {
conninfo := c.Context.Value(serverconnkey{}).(*stats.ConnTagInfo)
return conninfo.RemoteAddr.String()
}

// get the real peer's ip which will not be confused by proxy
func (c *ServerContext) GetRealPeerIp() string {
return c.peerip
}

// this function try to return the first caller's ip(mostly time it will be the user's ip)
// if can't get the first caller's ip,try to return the real peer's ip which will not be confused by proxy
// if failed,the direct peer's ip will be returned(maybe a proxy)
func (c *ServerContext) GetClientIp() string {
md := metadata.GetMetadata(c.Context)
return md["Client-IP"]
}

// ----------------------------------------------- no stream context ---------------------------------------------
func NewNoStreamServerContext(ctx *ServerContext) *NoStreamServerContext {
if ctx.decodefunc == nil {
return nil
}
return &NoStreamServerContext{Context: ctx.Context, sctx: ctx}
}

type NoStreamServerContext struct {
context.Context
sctx *ServerContext
}

func (c *NoStreamServerContext) GetPath() string {
return c.sctx.GetPath()
}

// get the direct peer's addr(maybe a proxy)
func (c *NoStreamServerContext) GetRemoteAddr() string {
return c.sctx.GetRemoteAddr()
}

// get the real peer's ip which will not be confused by proxy
func (c *NoStreamServerContext) GetRealPeerIp() string {
return c.sctx.GetRealPeerIp()
}

// this function try to return the first caller's ip(mostly time it will be the user's ip)
// if can't get the first caller's ip,try to return the real peer's ip which will not be confused by proxy
// if failed,the direct peer's ip will be returned(maybe a proxy)
func (c *NoStreamServerContext) GetClientIp() string {
return c.sctx.GetClientIp()
}

// ----------------------------------------------- client stream context ---------------------------------------------
func NewClientStreamServerContext[reqtype any](ctx *ServerContext, validatereq bool) *ClientStreamServerContext[reqtype] {
if ctx.stream == nil {
return nil
}
return &ClientStreamServerContext[reqtype]{
validatereq: validatereq,
Context: ctx.Context,
sctx: ctx,
}
}

type ClientStreamServerContext[reqtype any] struct {
validatereq bool
context.Context
sctx *ServerContext
}

func (c *ClientStreamServerContext[reqtype]) Recv() (*reqtype, error) {
var req any = new(reqtype)
if e := transGrpcError(c.sctx.stream.RecvMsg(req), false); e != nil {
if e != io.EOF {
slog.ErrorContext(c.Context, "["+c.sctx.path+"] read request failed", slog.String("error", e.Error()))
}
return nil, e
}
if c.validatereq {
if v, ok := req.(pbex.Validater); ok {
if errstr := v.Validate(); errstr != "" {
slog.ErrorContext(c.Context, "["+c.sctx.path+"] request validate failed", slog.String("error", errstr))
return nil, cerror.ErrReq
}
}
}
return req.(*reqtype), nil
}
func (c *ClientStreamServerContext[reqtype]) GetPath() string {
return c.sctx.GetPath()
}

// get the direct peer's addr(maybe a proxy)
func (c *ClientStreamServerContext[reqtype]) GetRemoteAddr() string {
return c.sctx.GetRemoteAddr()
}

// get the real peer's ip which will not be confused by proxy
func (c *ClientStreamServerContext[reqtype]) GetRealPeerIp() string {
return c.sctx.GetRealPeerIp()
}

// this function try to return the first caller's ip(mostly time it will be the user's ip)
// if can't get the first caller's ip,try to return the real peer's ip which will not be confused by proxy
// if failed,the direct peer's ip will be returned(maybe a proxy)
func (c *ClientStreamServerContext[reqtype]) GetClientIp() string {
return c.sctx.GetClientIp()
}

// ----------------------------------------------- server stream context ---------------------------------------------
func NewServerStreamServerContext[resptype any](ctx *ServerContext) *ServerStreamServerContext[resptype] {
if ctx.stream == nil {
return nil
}
return &ServerStreamServerContext[resptype]{
Context: ctx.Context,
sctx: ctx,
}
}

type ServerStreamServerContext[resptype any] struct {
context.Context
sctx *ServerContext
}

// Send will not wait peer to confirm accept the message,so there may be data lost if peer closed and self send at the same time
func (c *ServerStreamServerContext[resptype]) Send(resp *resptype) error {
e := transGrpcError(c.sctx.stream.SendMsg(resp), false)
if e != nil && e != io.EOF {
slog.ErrorContext(c.Context, "["+c.sctx.path+"] send response failed", slog.String("error", e.Error()))
}
return e
}
func (c *ServerStreamServerContext[resptype]) GetPath() string {
return c.sctx.GetPath()
}

// get the direct peer's addr(maybe a proxy)
func (c *ServerStreamServerContext[resptype]) GetRemoteAddr() string {
return c.sctx.GetRemoteAddr()
}

// get the real peer's ip which will not be confused by proxy
func (c *ServerStreamServerContext[resptype]) GetRealPeerIp() string {
return c.sctx.GetRealPeerIp()
}

// this function try to return the first caller's ip(mostly time it will be the user's ip)
// if can't get the first caller's ip,try to return the real peer's ip which will not be confused by proxy
// if failed,the direct peer's ip will be returned(maybe a proxy)
func (c *ServerStreamServerContext[resptype]) GetClientIp() string {
return c.sctx.GetClientIp()
}

// ----------------------------------------------- all stream context ---------------------------------------------
func NewAllStreamServerContext[reqtype, resptype any](ctx *ServerContext, validatereq bool) *AllStreamServerContext[reqtype, resptype] {
if ctx.stream == nil {
return nil
}
return &AllStreamServerContext[reqtype, resptype]{
validatereq: validatereq,
Context: ctx.Context,
sctx: ctx,
}
}

type AllStreamServerContext[reqtype, resptype any] struct {
validatereq bool
context.Context
sctx *ServerContext
}

func (c *AllStreamServerContext[reqtype, resptype]) Recv() (*reqtype, error) {
var req any = new(reqtype)
if e := transGrpcError(c.sctx.stream.RecvMsg(req), false); e != nil {
if e != io.EOF {
slog.ErrorContext(c.Context, "["+c.sctx.path+"] read request failed", slog.String("error", e.Error()))
}
return nil, e
}
if c.validatereq {
if v, ok := req.(pbex.Validater); ok {
if errstr := v.Validate(); errstr != "" {
slog.ErrorContext(c.Context, "["+c.sctx.path+"] request validate failed", slog.String("error", errstr))
return nil, cerror.ErrReq
}
}
}
return req.(*reqtype), nil
}

// Send will not wait peer to confirm accept the message,so there may be data lost if peer closed and self send at the same time
func (c *AllStreamServerContext[reqtype, resptype]) Send(resp *resptype) error {
e := transGrpcError(c.sctx.stream.SendMsg(resp), false)
if e != nil && e != io.EOF {
slog.ErrorContext(c.Context, "["+c.sctx.path+"] send response failed", slog.String("error", e.Error()))
}
return e
}
func (c *AllStreamServerContext[reqtype, resptype]) GetPath() string {
return c.sctx.GetPath()
}

// get the direct peer's addr(maybe a proxy)
func (c *AllStreamServerContext[reqtype, resptype]) GetRemoteAddr() string {
return c.sctx.GetRemoteAddr()
}

// get the real peer's ip which will not be confused by proxy
func (c *AllStreamServerContext[reqtype, resptype]) GetRealPeerIp() string {
return c.sctx.GetRealPeerIp()
}

// this function try to return the first caller's ip(mostly time it will be the user's ip)
// if can't get the first caller's ip,try to return the real peer's ip which will not be confused by proxy
// if failed,the direct peer's ip will be returned(maybe a proxy)
func (c *AllStreamServerContext[reqtype, resptype]) GetClientIp() string {
return c.sctx.GetClientIp()
}
4 changes: 2 additions & 2 deletions codegen/README.md
Original file line number Diff line number Diff line change
@@ -19,8 +19,8 @@
linux/max: 终端切换工作目录到项目目录,执行 ./cmd.sh pb
windows: 终端切换工作目录到项目目录,执行 ./cmd.bat pb
### 4.创建子服务
linux/mac: 终端切换工作目录到项目目录,执行 ./cmd.sh new "sub service name"
windows: 终端切换工作目录到项目目录,执行 ./cmd.bat new "sub service name"
linux/mac: 终端切换工作目录到项目目录,执行 ./cmd.sh sub "sub service name"
windows: 终端切换工作目录到项目目录,执行 ./cmd.bat sub "sub service name"
### 5.更新kuberneters配置
linux/mac: 终端切换工作目录到项目目录,执行 ./cmd.sh kube
windows: 终端切换工作目录到项目目录,执行 ./cmd.bat kube
478 changes: 269 additions & 209 deletions codegen/main.go

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions codegen/tml/api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package api

import (
"os"
)

const txt = `package api
// Don't delete!
// This file is a placeholder for the package name!`

func CreatePathAndFile() {
if e := os.MkdirAll("./api/", 0755); e != nil {
panic("mkdir ./api/ error: " + e.Error())
}
file, e := os.OpenFile("./api/api.go", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic("open ./api/api.go error: " + e.Error())
}
if _, e := file.WriteString(txt); e != nil {
panic("write ./api/api.go error: " + e.Error())
}
if e := file.Sync(); e != nil {
panic("sync ./api/api.go error: " + e.Error())
}
if e := file.Close(); e != nil {
panic("close ./api/api.go error: " + e.Error())
}
}
57 changes: 0 additions & 57 deletions codegen/tml/api/client/client.go

This file was deleted.

64 changes: 33 additions & 31 deletions codegen/tml/api/status/template_status.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package status

import (
"fmt"
"os"
"text/template"
)

const text = `syntax="proto3";
const txt = `syntax="proto3";
//this is the proto package name,all proto in this project must use this name as the proto package name
//this is the app's name,all proto in this app must use this name as the proto package name
package {{.ProjectName}};
//this is the golang's package name,all proto in this project must use this name as the golang's package name
option go_package="{{.PackageName}}/api;api";
@@ -20,12 +19,8 @@ service status{
//ping check server's health
rpc ping(pingreq)returns(pingresp){
option (pbex.method)="get";
option (pbex.web_midwares)="accesskey";
option (pbex.web_midwares)="rate";
option (pbex.crpc_midwares)="accesskey";
option (pbex.crpc_midwares)="rate";
option (pbex.cgrpc_midwares)="accesskey";
option (pbex.cgrpc_midwares)="rate";
option (pbex.method)="crpc";
option (pbex.method)="grpc";
}
}
//req can be set with pbex extentions
@@ -36,38 +31,45 @@ message pingreq{
message pingresp{
int64 client_timestamp=1;
int64 server_timestamp=2;
uint64 total_mem=3;
uint64 cur_mem_usage=4;
uint64 max_mem_usage=5;
double cpu_num=6;
double cur_cpu_usage=7;
double avg_cpu_usage=8;
double max_cpu_usage=9;
string host=10;
string ip=11;
}`

const path = "./api/"
const name = "status.proto"

var tml *template.Template
var file *os.File

type data struct {
PackageName string
ProjectName string
}

func init() {
var e error
tml, e = template.New("api").Parse(text)
if e != nil {
panic(fmt.Sprintf("create template error:%s", e))
func CreatePathAndFile(packagename, projectname string) {
tmp := &data{
PackageName: packagename,
ProjectName: projectname,
}
}
func CreatePathAndFile() {
var e error
if e = os.MkdirAll(path, 0755); e != nil {
panic(fmt.Sprintf("make dir:%s error:%s", path, e))
if e := os.MkdirAll("./api/", 0755); e != nil {
panic("mkdir ./api/ error: " + e.Error())
}
file, e = os.OpenFile(path+name, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
prototemplate, e := template.New("./api/" + projectname + "_status.proto").Parse(txt)
if e != nil {
panic(fmt.Sprintf("make file:%s error:%s", path+name, e))
panic("parse ./api/" + projectname + "_status.proto error: " + e.Error())
}
}
func Execute(PackageName, ProjectName string) {
if e := tml.Execute(file, &data{PackageName: PackageName, ProjectName: ProjectName}); e != nil {
panic(fmt.Sprintf("write content into file:%s error:%s", path+name, e))
file, e := os.OpenFile("./api/"+projectname+"_status.proto", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic("open ./api/" + projectname + "_status.proto error: " + e.Error())
}
if e := prototemplate.Execute(file, tmp); e != nil {
panic("write ./api/" + projectname + "_status.proto error: " + e.Error())
}
if e := file.Sync(); e != nil {
panic("sync ./api/" + projectname + "_status.proto error: " + e.Error())
}
if e := file.Close(); e != nil {
panic("close ./api/" + projectname + "_status.proto error: " + e.Error())
}
}
51 changes: 26 additions & 25 deletions codegen/tml/api/sub/template_sub.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package sub

import (
"fmt"
"os"
"text/template"
)

const text = `syntax="proto3";
const txt = `syntax="proto3";
//this is the proto package name,all proto in this project must use this name as the proto package name
//this is the app's name,all proto in this app must use this name as the proto package name
package {{.ProjectName}};
//this is the golang's package name,all proto in this project must use this name as the golang's package name
option go_package="{{.PackageName}}/api;api";
@@ -18,7 +17,9 @@ import "pbex/pbex.proto";
//this is the proto file for {{.Sname}} service
service {{.Sname}}{
//rpc example(examplereq)returns(exampleresp){
// option (pbex.method)="get";//can be set to get,delete,post,put,patch
// option (pbex.method)="get";
// option (pbex.method)="crpc";
// option (pbex.method)="grpc";//can be set to one of (get,delete,post,put,patch) or crpc or grpc
// option (pbex.web_midwares)="b";
// option (pbex.web_midwares)="c";
// option (pbex.web_midwares)="a";//this function on web protocol has 3 midwares,it's order is b,c,a
@@ -39,36 +40,36 @@ service {{.Sname}}{
//int64 example_resp=1;
//}`

const path = "./api/"

var tml *template.Template
var file *os.File

type data struct {
PackageName string
ProjectName string
Sname string
}

func init() {
var e error
tml, e = template.New("api").Parse(text)
if e != nil {
panic(fmt.Sprintf("create template error:%s", e))
func CreatePathAndFile(packagename, projectname, sname string) {
tmp := &data{
PackageName: packagename,
ProjectName: projectname,
Sname: sname,
}
}
func CreatePathAndFile(sname string) {
var e error
if e = os.MkdirAll(path, 0755); e != nil {
panic(fmt.Sprintf("make dir:%s error:%s", path, e))
if e := os.MkdirAll("./api/", 0755); e != nil {
panic("mkdir ./api/ error: " + e.Error())
}
file, e = os.OpenFile(path+sname+".proto", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
prototemplate, e := template.New("./api/" + projectname + "_" + sname + ".proto").Parse(txt)
if e != nil {
panic(fmt.Sprintf("make file:%s error:%s", path+sname+".proto", e))
panic("parse ./api/" + projectname + "_" + sname + ".proto error: " + e.Error())
}
}
func Execute(PackageName, ProjectName, Sname string) {
if e := tml.Execute(file, &data{PackageName: PackageName, ProjectName: ProjectName, Sname: Sname}); e != nil {
panic(fmt.Sprintf("write content into file:%s error:%s", path+Sname+".proto", e))
file, e := os.OpenFile("./api/"+projectname+"_"+sname+".proto", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic("open ./api/" + projectname + "_" + sname + ".proto error: " + e.Error())
}
if e := prototemplate.Execute(file, tmp); e != nil {
panic("write ./api/" + projectname + "_" + sname + ".proto error: " + e.Error())
}
if e := file.Sync(); e != nil {
panic("sync ./api/" + projectname + "_" + sname + ".proto error: " + e.Error())
}
if e := file.Close(); e != nil {
panic("close ./api/" + projectname + "_" + sname + ".proto error: " + e.Error())
}
}
257 changes: 170 additions & 87 deletions codegen/tml/cmd/template_cmd.go

Large diffs are not rendered by default.

1,026 changes: 482 additions & 544 deletions codegen/tml/config/template_config.go

Large diffs are not rendered by default.

239 changes: 134 additions & 105 deletions codegen/tml/configfile/template_configfile.go
Original file line number Diff line number Diff line change
@@ -1,166 +1,195 @@
package configfile

import (
"fmt"
"os"
"text/template"
)

const textsource = `{
const source = `{
"raw_server":{
"connect_timeout":"500ms",
"heart_probe":"10s",
"group_num":100,
"certs":{
}
},
"cgrpc_server":{
"connect_timeout":"200ms",
"global_timeout":"200ms",
"heart_probe":"1.5s"
"connect_timeout":"500ms",
"idle_timeout":"0",
"global_timeout":"500ms",
"heart_probe":"10s",
"certs":{
}
},
"cgrpc_client":{
"connect_timeout":"200ms",
"connect_timeout":"500ms",
"idle_timeout":"0",
"global_timeout":"0",
"heart_probe":"1.5s"
"heart_probe":"10s"
},
"crpc_server":{
"connect_timeout":"200ms",
"global_timeout":"200ms",
"heart_probe":"1.5s"
"connect_timeout":"500ms",
"idle_timeout":"0",
"global_timeout":"500ms",
"heart_probe":"10s",
"certs":{
}
},
"crpc_client":{
"connect_timeout":"200ms",
"connect_timeout":"500ms",
"idle_timeout":"0",
"global_timeout":"0",
"heart_probe":"1.5s"
"heart_probe":"10s"
},
"web_server":{
"close_mode":0,
"connect_timeout":"200ms",
"global_timeout":"200ms",
"wait_close_mode":0,
"wait_close_time":"1s",
"connect_timeout":"500ms",
"global_timeout":"500ms",
"idle_timeout":"5s",
"heart_probe":"1.5s",
"static_file":"./src",
"web_cors":{
"cors_origin":["*"],
"cors_header":["*"],
"cors_expose":[]
"max_request_header":4096,
"cors_allowed_origins":["*"],
"cors_allowed_headers":["*"],
"cors_expose_headers":["*"],
"cors_allow_credentials":false,
"cors_max_age":"30m",
"src_root_path":"",
"certs":{
}
},
"web_client":{
"connect_timeout":"200ms",
"connect_timeout":"500ms",
"global_timeout":"0",
"idle_timeout":"5s",
"heart_probe":"1.5s"
"max_response_header":4096
},
"mongo":{
"example_mongo":{
"url":"[mongodb/mongodb+srv]://[username:password@]host1,...,hostN[/dbname][?param1=value1&...&paramN=valueN]",
"max_open":100,
"max_idletime":"10m",
"tls":false,
"specific_ca_paths":["./example.pem"],
"mongodb_srv":false,
"addrs":["127.0.0.1:27017"],
"user_name":"",
"password":"",
"auth_db":"",
"replica_set":"",
"max_open":256,
"max_conn_idletime":"5m",
"io_timeout":"500ms",
"conn_timeout":"500ms"
"dial_timeout":"250ms"
}
},
"sql":{
"example_sql":{
"url":"[username:password@][protocol(address)][/dbname][?param1=value1&...&paramN=valueN]",
"max_open":100,
"max_idletime":"10m",
"io_timeout":"200ms",
"conn_timeout":"200ms"
"mysql":{
"example_mysql":{
"tls":false,
"specific_ca_paths":["./example.pem"],
"master":{
"addr":"127.0.0.1:3306",
"user_name":"root",
"password":""
},
"slaves":{
"addrs":[],
"user_name":"",
"password":""
},
"max_open":256,
"max_conn_idletime":"5m",
"io_timeout":"500ms",
"dial_timeout":"250ms",
"charset":"",
"collation":"",
"parse_time":true
}
},
"redis":{
"example_redis":{
"url":"[redis/rediss]://[[username:]password@]host[/dbindex]",
"max_open":100,
"max_idletime":"10m",
"io_timeout":"200ms",
"conn_timeout":"200ms"
}
},
"kafka_pub":[
{
"addrs":["127.0.0.1:12345"],
"username":"example",
"password":"example",
"auth_method":3,
"compress_method":2,
"topic_name":"example_topic",
"tls":false,
"specific_ca_paths":["./example.pem"],
"redis_mode":"direct",
"addrs":["127.0.0.1:6379"],
"user_name":"",
"password":"",
"sentinel_master_name":"",
"read_write_split":true,
"max_open":256,
"max_conn_idletime":"5m",
"io_timeout":"500ms",
"conn_timeout":"200ms"
}
],
"kafka_sub":[
{
"addrs":["127.0.0.1:12345"],
"username":"example",
"password":"example",
"auth_method":3,
"topic_name":"example_topic",
"group_name":"example_group",
"conn_timeout":"200ms",
"start_offset":-2,
"commit_interval":"0s"
"dial_timeout":"250ms"
}
]
}
}`
const textapp = `{
const app = `{
"handler_timeout":{
"/{{.}}.status/ping":{
"GET":"200ms",
"CRPC":"200ms",
"GRPC":"200ms"
}
},
"handler_rate":[{
"Path":"/{{.}}.status/ping",
"Method":["GET","GRPC","CRPC"],
"MaxPerSec":10
}],
"access_keys":{
"default":"default_sec_key",
"/{{.}}.status/ping":"specific_sec_key"
"web_path_rewrite":{
"GET":{
"/origin/url":"/{{.}}.exampleservice/examplemethod"
}
},
"handler_rate":{
"/{{.}}.exampleservice/examplemethod":[{
"methods":["GET","GRPC","CRPC"],
"max_rate":10,
"period":1,
"rate_type":"path"
},{
"methods":["GET","GRPC","CRPC"],
"max_rate":10,
"period":1,
"rate_type":"token"
}]
},
"accesses":{
"/{{.}}.exampleservice/examplemethod":[{
"methods":["GET","GRPC","CRPC"],
"accesses":{
"accessid":"accesskey"
}
}]
},
"token_secret":"test",
"service":{
}
}`

const path = "./"
const sourcename = "SourceConfig.json"
const appname = "AppConfig.json"

var tmlsource *template.Template
var tmlapp *template.Template

var filesource *os.File
var fileapp *os.File

func init() {
var e error
tmlsource, e = template.New("source").Parse(textsource)
func CreatePathAndFile(projectname string) {
//./SourceConfig.json
sourcefile, e := os.OpenFile("./SourceConfig.json", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic(fmt.Sprintf("create template error:%s", e))
panic("open ./SourceConfig.json error: " + e.Error())
}
tmlapp, e = template.New("app").Parse(textapp)
if e != nil {
panic(fmt.Sprintf("create template error:%s", e))
if _, e := sourcefile.WriteString(source); e != nil {
panic("write ./SourceConfig.json error: " + e.Error())
}
}
func CreatePathAndFile() {
var e error
if e = os.MkdirAll(path, 0755); e != nil {
panic(fmt.Sprintf("make dir:%s error:%s", path, e))
if e := sourcefile.Sync(); e != nil {
panic("sync ./SourceConfig.json error: " + e.Error())
}
if e := sourcefile.Close(); e != nil {
panic("close ./SourceConfig.json error: " + e.Error())
}
filesource, e = os.OpenFile(path+sourcename, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
//./AppConfig.json
apptemplate, e := template.New("./AppConfig.json").Parse(app)
if e != nil {
panic(fmt.Sprintf("make file:%s error:%s", path+sourcename, e))
panic("parse ./AppConfig.json template error: " + e.Error())
}
fileapp, e = os.OpenFile(path+appname, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
appfile, e := os.OpenFile("./AppConfig.json", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic(fmt.Sprintf("make file:%s error:%s", path+appname, e))
panic("open ./AppConfig.json error: " + e.Error())
}
}
func Execute(projectname string) {
if e := tmlsource.Execute(filesource, projectname); e != nil {
panic(fmt.Sprintf("write content into file:%s error:%s", path+sourcename, e))
if e := apptemplate.Execute(appfile, projectname); e != nil {
panic("write ./AppConfig.json error: " + e.Error())
}
if e := appfile.Sync(); e != nil {
panic("sync ./AppConfig.json error: " + e.Error())
}
if e := tmlapp.Execute(fileapp, projectname); e != nil {
panic(fmt.Sprintf("write content into file:%s error:%s", path+appname, e))
if e := appfile.Close(); e != nil {
panic("close ./AppConfig.json error: " + e.Error())
}
}
141 changes: 70 additions & 71 deletions codegen/tml/dao/sub/template_sub.go
Original file line number Diff line number Diff line change
@@ -1,114 +1,113 @@
package sub

import (
"fmt"
"os"
"text/template"
)

const text = `package {{.}}
const dao = `package {{.}}
import (
csql "database/sql"
cmongo "github.com/chenjie199234/Corelib/mongo"
cmysql "github.com/chenjie199234/Corelib/mysql"
credis "github.com/chenjie199234/Corelib/redis"
cmongo "go.mongodb.org/mongo-driver/mongo"
)
//Dao this is a data operation layer to operate {{.}} service's data
// Dao this is a data operation layer to operate {{.}} service's data
type Dao struct {
sql *csql.DB
redis *credis.Pool
mysql *cmysql.Client
redis *credis.Client
mongo *cmongo.Client
}
//NewDao Dao is only a data operation layer
//don't write business logic in this package
//business logic should be written in service package
func NewDao(sql *csql.DB, redis *credis.Pool, mongo *cmongo.Client) *Dao {
// NewDao Dao is only a data operation layer
// don't write business logic in this package
// business logic should be written in service package
func NewDao(mysql *cmysql.Client, redis *credis.Client, mongo *cmongo.Client) *Dao {
return &Dao{
sql: sql,
mysql: mysql,
redis: redis,
mongo: mongo,
}
}`
const textsql = `package {{.}}`
const textredis = `package {{.}}`
const textmongo = `package {{.}}`

const path = "./dao/"
const name = "dao.go"
const namesql = "sql.go"
const nameredis = "redis.go"
const namemongo = "mongo.go"

var tml *template.Template
var tmlsql *template.Template
var tmlredis *template.Template
var tmlmongo *template.Template

var file *os.File
var filesql *os.File
var fileredis *os.File
var filemongo *os.File

type data struct {
Pname string
Sname string
}
const sql = `package {{.}}`
const redis = `package {{.}}`
const mongo = `package {{.}}`

func init() {
var e error
tml, e = template.New("dao").Parse(text)
func CreatePathAndFile(sname string) {
if e := os.MkdirAll("./dao/"+sname+"/", 0755); e != nil {
panic("mkdir ./dao/" + sname + "/ error: " + e.Error())
}
//dao.go
daotemplate, e := template.New("./dao/" + sname + "/dao.go").Parse(dao)
if e != nil {
panic(fmt.Sprintf("create template error:%s", e))
panic("parse ./dao/" + sname + "/dao.go template error: " + e.Error())
}
tmlsql, e = template.New("sql").Parse(textsql)
daofile, e := os.OpenFile("./dao/"+sname+"/dao.go", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic(fmt.Sprintf("create template error:%s", e))
panic("open ./dao/" + sname + "/dao.go error: " + e.Error())
}
if e := daotemplate.Execute(daofile, sname); e != nil {
panic("write ./dao/" + sname + "/dao.go error: " + e.Error())
}
if e := daofile.Sync(); e != nil {
panic("sync ./dao/" + sname + "/dao.go error: " + e.Error())
}
tmlredis, e = template.New("redis").Parse(textredis)
if e := daofile.Close(); e != nil {
panic("close ./dao/" + sname + "/dao.go error: " + e.Error())
}
//sql.go
sqltemplate, e := template.New("./dao/" + sname + "/sql.go").Parse(sql)
if e != nil {
panic(fmt.Sprintf("create template error:%s", e))
panic("parse ./dao/" + sname + "/sql.go template error: " + e.Error())
}
tmlmongo, e = template.New("mongo").Parse(textmongo)
sqlfile, e := os.OpenFile("./dao/"+sname+"/sql.go", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic(fmt.Sprintf("create template error:%s", e))
panic("open ./dao/" + sname + "/sql.go error: " + e.Error())
}
}
func CreatePathAndFile(sname string) {
var e error
if e = os.MkdirAll(path+sname+"/", 0755); e != nil {
panic(fmt.Sprintf("make dir:%s error:%s", path, e))
if e := sqltemplate.Execute(sqlfile, sname); e != nil {
panic("write ./dao/" + sname + "/sql.go error: " + e.Error())
}
file, e = os.OpenFile(path+sname+"/"+name, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic(fmt.Sprintf("make file:%s error:%s", path+sname+"/"+name, e))
if e := sqlfile.Sync(); e != nil {
panic("sync ./dao/" + sname + "/sql.go error: " + e.Error())
}
if e := sqlfile.Close(); e != nil {
panic("close ./dao/" + sname + "/sql.go error: " + e.Error())
}
filesql, e = os.OpenFile(path+sname+"/"+namesql, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
//mongo.go
mongotemplate, e := template.New("./dao/" + sname + "/mongo.go").Parse(mongo)
if e != nil {
panic(fmt.Sprintf("make file:%s error:%s", path+sname+"/"+namesql, e))
panic("parse ./dao/" + sname + "/mongo.go template error: " + e.Error())
}
fileredis, e = os.OpenFile(path+sname+"/"+nameredis, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
mongofile, e := os.OpenFile("./dao/"+sname+"/mongo.go", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic(fmt.Sprintf("make file:%s error:%s", path+sname+"/"+nameredis, e))
panic("open ./dao/" + sname + "/mongo.go error: " + e.Error())
}
filemongo, e = os.OpenFile(path+sname+"/"+namemongo, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e := mongotemplate.Execute(mongofile, sname); e != nil {
panic("write ./dao/" + sname + "/mongo.go error: " + e.Error())
}
if e := mongofile.Sync(); e != nil {
panic("sync ./dao/" + sname + "/mongo.go error: " + e.Error())
}
if e := mongofile.Close(); e != nil {
panic("close ./dao/" + sname + "/mongo.go error: " + e.Error())
}
//redis.go
redistemplate, e := template.New("./dao/" + sname + "/redis.go").Parse(redis)
if e != nil {
panic(fmt.Sprintf("make file:%s error:%s", path+sname+"/"+namemongo, e))
panic("parse ./dao/" + sname + "/redis.go template error: " + e.Error())
}
}
func Execute(sname string) {
if e := tml.Execute(file, sname); e != nil {
panic(fmt.Sprintf("write content into file:%s error:%s", path+sname+"/"+name, e))
redisfile, e := os.OpenFile("./dao/"+sname+"/redis.go", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic("open ./dao/" + sname + "/redis.go error: " + e.Error())
}
if e := tmlsql.Execute(filesql, sname); e != nil {
panic(fmt.Sprintf("write content into file:%s error:%s", path+sname+"/"+namesql, e))
if e := redistemplate.Execute(redisfile, sname); e != nil {
panic("write ./dao/" + sname + "/redis.go error: " + e.Error())
}
if e := tmlredis.Execute(fileredis, sname); e != nil {
panic(fmt.Sprintf("write content into file:%s error:%s", path+sname+"/"+nameredis, e))
if e := redisfile.Sync(); e != nil {
panic("sync ./dao/" + sname + "/redis.go error: " + e.Error())
}
if e := tmlmongo.Execute(filemongo, sname); e != nil {
panic(fmt.Sprintf("write content into file:%s error:%s", path+sname+"/"+namemongo, e))
if e := redisfile.Close(); e != nil {
panic("close ./dao/" + sname + "/redis.go error: " + e.Error())
}
}
168 changes: 65 additions & 103 deletions codegen/tml/dao/template_dao.go
Original file line number Diff line number Diff line change
@@ -1,60 +1,91 @@
package dao

import (
"fmt"
"os"
"text/template"
)

const text = `package dao
const txt = `package dao
import (
"net"
"time"
//"{{.}}/api"
//example "{{.}}/api/deps/example"
"{{.}}/config"
// "{{.}}/model"
"github.com/chenjie199234/Corelib/cgrpc"
"github.com/chenjie199234/Corelib/crpc"
"github.com/chenjie199234/Corelib/web"
// admindiscover "github.com/chenjie199234/admin/sdk/discover"
// "github.com/chenjie199234/Corelib/discover"
// "github.com/chenjie199234/Corelib/cgrpc"
// "github.com/chenjie199234/Corelib/crpc"
// "github.com/chenjie199234/Corelib/web"
)
//var ExampleCGrpcApi example.ExampleCGrpcClient
//var ExampleCrpcApi example.ExampleCrpcClient
//var ExampleWebApi example.ExampleWebClient
//NewApi create all dependent service's api we need in this program
// NewApi create all dependent service's api we need in this program
func NewApi() error {
var e error
_ = e //avoid unuse
//init dns discover for example server
//exampleDnsDiscover, e := discover.NewDNSDiscover("exampleproject", "examplegroup", "examplename", "dnshost", time.Second*10, 9000, 10000, 8000)
//if e != nil {
// return e
//}
//
//init static discover for example server
//exampleStaticDiscover, e := discover.NewStaticDiscover("exampleproject", "examplegroup", "examplename", []string{"addr1","addr2"}, 9000, 10000, 8000)
//if e != nil {
// return e
//}
//
//init kubernetes discover for example server
//exampleKubeDiscover, e := discover.NewKubernetesDiscover("exampleproject", "examplegroup", "examplename", "namespace", "fieldselector", "labelselector", 9000, 10000, 8000)
//if e != nil {
// return e
//}
//
//init admin discover for example server
//if admin service needs tls,you need to specific the config
//var admintlsc *tlsc.Config{}
//if adminNeedTLS {
// admintlsc = &tlsc.Config{}
// ...
//}
//exampleAdminDiscover, e := admindiscover.NewAdminDiscover("exampleproject", "examplegroup", "examplename", admintlsc)
//if e != nil {
// return e
//}
//if example service needs tls,you need to specific the config
//var exampletlsc *tls.Config
// if exampleNeedTLS {
// exampletlsc = &tls.Config{}
// ...
// }
cgrpcc := getCGrpcClientConfig()
cgrpcc := config.GetCGrpcClientConfig().ClientConfig
_ = cgrpcc //avoid unuse
//init cgrpc client below
//examplecgrpc e = cgrpc.NewCGrpcClient(cgrpcc, api.Group, api.Name, "examplegroup", "examplename")
//examplecgrpc, e := cgrpc.NewCGrpcClient(cgrpcc, examplediscover, "exampleproject", "examplegroup", "examplename", exampletlsc)
//if e != nil {
// return e
//}
//ExampleCGrpcApi = example.NewExampleCGrpcClient(examplecgrpc)
crpcc := getCrpcClientConfig()
crpcc := config.GetCrpcClientConfig().ClientConfig
_ = crpcc //avoid unuse
//init crpc client below
//examplecrpc, e = crpc.NewCrpcClient(crpcc, api.Group, api.Name, "examplegroup", "examplename")
//examplecrpc, e := crpc.NewCrpcClient(crpcc, examplediscover, "exampleproject", "examplegroup", "examplename", exampletlsc)
//if e != nil {
// return e
//}
//ExampleCrpcApi = example.NewExampleCrpcClient(examplecrpc)
webc := getWebClientConfig()
webc := config.GetWebClientConfig().ClientConfig
_ = webc //avoid unuse
//init web client below
//exampleweb, e = web.NewWebClient(webc, api.Group, api.Name, "examplegroup", "examplename", "http://examplehost:exampleport")
//exampleweb, e := web.NewWebClient(webc, examplediscover, "exampleproject", "examplegroup", "examplename", exampletlsc)
//if e != nil {
// return e
//}
@@ -63,98 +94,29 @@ func NewApi() error {
return nil
}
func getCGrpcClientConfig() *cgrpc.ClientConfig {
gc := config.GetCGrpcClientConfig()
return &cgrpc.ClientConfig{
ConnectTimeout: time.Duration(gc.ConnectTimeout),
GlobalTimeout: time.Duration(gc.GlobalTimeout),
HeartPorbe: time.Duration(gc.HeartProbe),
Discover: cgrpcDNS,
DiscoverInterval: time.Second * 10,
}
}
func UpdateAppConfig(ac *config.AppConfig) {
func cgrpcDNS(group, name string) (map[string]*cgrpc.RegisterData, error) {
result := make(map[string]*cgrpc.RegisterData)
addrs, e := net.LookupHost(name + "-service-headless." + group)
if e != nil {
return nil, e
}
for i := range addrs {
addrs[i] = addrs[i] + ":10000"
}
dserver := make(map[string]*struct{})
dserver["dns"] = nil
for _, addr := range addrs {
result[addr] = &cgrpc.RegisterData{DServers: dserver}
}
return result,nil
}
}`

func getCrpcClientConfig() *crpc.ClientConfig {
rc := config.GetCrpcClientConfig()
return &crpc.ClientConfig{
ConnectTimeout: time.Duration(rc.ConnectTimeout),
GlobalTimeout: time.Duration(rc.GlobalTimeout),
HeartPorbe: time.Duration(rc.HeartProbe),
Discover: crpcDNS,
DiscoverInterval: time.Second * 10,
func CreatePathAndFile(packagename string) {
if e := os.MkdirAll("./dao/", 0755); e != nil {
panic("mkdir ./dao/ error: " + e.Error())
}
}
func crpcDNS(group, name string) (map[string]*crpc.RegisterData, error) {
result := make(map[string]*crpc.RegisterData)
addrs, e := net.LookupHost(name + "-service-headless." + group)
daotemplate, e := template.New("./dao/dao.go").Parse(txt)
if e != nil {
return nil, e
}
for i := range addrs {
addrs[i] = addrs[i] + ":9000"
}
dserver := make(map[string]*struct{})
dserver["dns"] = nil
for _, addr := range addrs {
result[addr] = &crpc.RegisterData{DServers: dserver}
}
return result, nil
}
func getWebClientConfig() *web.ClientConfig {
wc := config.GetWebClientConfig()
return &web.ClientConfig{
ConnectTimeout: time.Duration(wc.ConnectTimeout),
GlobalTimeout: time.Duration(wc.GlobalTimeout),
IdleTimeout: time.Duration(wc.IdleTimeout),
HeartProbe: time.Duration(wc.HeartProbe),
MaxHeader: 1024,
panic("parse ./dao/dao.go template error: " + e.Error())
}
}`

const path = "./dao/"
const name = "dao.go"

var tml *template.Template
var file *os.File

func init() {
var e error
tml, e = template.New("dao").Parse(text)
file, e := os.OpenFile("./dao/dao.go", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic(fmt.Sprintf("create template error:%s", e))
panic("open ./dao/dao.go error: " + e.Error())
}
}
func CreatePathAndFile() {
var e error
if e = os.MkdirAll(path, 0755); e != nil {
panic(fmt.Sprintf("make dir:%s error:%s", path, e))
if e := daotemplate.Execute(file, packagename); e != nil {
panic("write ./dao/dao.go error: " + e.Error())
}
file, e = os.OpenFile(path+name, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic(fmt.Sprintf("make file:%s error:%s", path+name, e))
if e := file.Sync(); e != nil {
panic("sync ./dao/dao.go error: " + e.Error())
}
}
func Execute(PackageName string) {
if e := tml.Execute(file, PackageName); e != nil {
panic(fmt.Sprintf("write content into file:%s error:%s", path+name, e))
if e := file.Close(); e != nil {
panic("close ./dao/dao.go error: " + e.Error())
}
}
263 changes: 263 additions & 0 deletions codegen/tml/deploy/deploy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
package deploy

import (
"os"
"text/template"
)

const docker = `FROM golang:1.24.1 as builder
ENV GOSUMDB='off' \
GOOS='linux' \
GOARCH='amd64' \
CGO_ENABLED=0
RUN mkdir /code
ADD . /code
WORKDIR /code
RUN echo "start build" && go mod tidy && go build -o main && echo "end build"
FROM debian:stable
RUN apt-get update && apt-get install -y ca-certificates curl inetutils-telnet inetutils-ping inetutils-traceroute dnsutils iproute2 procps net-tools neovim && mkdir /root/app
WORKDIR /root/app
EXPOSE 6060 7000 8000 9000 10000
COPY --from=builder /code/main /code/AppConfig.json /code/SourceConfig.json ./
ENTRYPOINT ["./main"]`

const deployment = `apiVersion: apps/v1
kind: Deployment
metadata:
name: {{.AppName}}-deployment
namespace: <PROJECT>-<GROUP>
labels:
app: {{.AppName}}
spec:
replicas: 2
minReadySeconds: 5
progressDeadlineSeconds: 300
revisionHistoryLimit: 5
selector:
matchLabels:
app: {{.AppName}}
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: {{.AppName}}
spec:
containers:
- name: {{.AppName}}
image: <IMAGE>
imagePullPolicy: IfNotPresent
ports:
- name: web
protocol: TCP
containerPort: 8000
- name: crpc
protocol: TCP
containerPort: 9000
- name: grpc
protocol: TCP
containerPort: 10000
resources:
limits:
memory: 4096Mi
cpu: 4000m
requests:
memory: 256Mi
cpu: 250m
env:
- name: HOSTIP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: GROUP
value: <GROUP>
- name: PROJECT
value: <PROJECT>
- name: TRACE
value: <TRACE>
- name: ZIPKIN_URL
value: <ZIPKIN_URL>
- name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
value: <OTEL_EXPORTER_OTLP_TRACES_ENDPOINT>
- name: METRIC
value: <METRIC>
- name: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
value: <OTEL_EXPORTER_OTLP_METRICS_ENDPOINT>
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: <OTEL_EXPORTER_OTLP_ENDPOINT>
- name: DEPLOY_ENV
value: <DEPLOY_ENV>
- name: RUN_ENV
value: <RUN_ENV>
- name: CONFIG_TYPE
value: <CONFIG_TYPE>
- name: REMOTE_CONFIG_SECRET
value: <REMOTE_CONFIG_SECRET>
- name: ADMIN_SERVICE_PROJECT
value: <ADMIN_SERVICE_PROJECT>
- name: ADMIN_SERVICE_GROUP
value: <ADMIN_SERVICE_GROUP>
- name: ADMIN_SERVICE_WEB_HOST
value: <ADMIN_SERVICE_WEB_HOST>
- name: ADMIN_SERVICE_WEB_PORT
value: <ADMIN_SERVICE_WEB_PORT>
- name: ADMIN_SERVICE_CONFIG_ACCESS_KEY
value: <ADMIN_SERVICE_CONFIG_ACCESS_KEY>
- name: ADMIN_SERVICE_DISCOVER_ACCESS_KEY
value: <ADMIN_SERVICE_DISCOVER_ACCESS_KEY>
- name: ADMIN_SERVICE_PERMISSION_ACCESS_KEY
value: <ADMIN_SERVICE_PERMISSION_ACCESS_KEY>
startupProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 1
successThreshold: 1
failureThreshold: 3
livenessProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 1
successThreshold: 1
failureThreshold: 3
imagePullSecrets:
- name: <PROJECT>-<GROUP>-secret
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{.AppName}}-hpa
namespace: <PROJECT>-<GROUP>
labels:
app: {{.AppName}}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{.AppName}}-deployment
maxReplicas: 10
minReplicas: 2
metrics:
- type: Resource
resource:
name: memory
target:
type: AverageValue
averageValue: 3500Mi
- type: Resource
resource:
name: cpu
target:
type: AverageValue
averageValue: 3400m{{ if .NeedService }}
---
apiVersion: v1
kind: Service
metadata:
name: {{.AppName}}-headless
namespace: <PROJECT>-<GROUP>
labels:
app: {{.AppName}}
spec:
type: ClusterIP
clusterIP: None
ports:
- name: crpc
protocol: TCP
port: 9000
- name: grpc
protocol: TCP
port: 10000
selector:
app: {{.AppName}}
---
apiVersion: v1
kind: Service
metadata:
name: {{.AppName}}
namespace: <PROJECT>-<GROUP>
labels:
app: {{.AppName}}
spec:
type: ClusterIP
ports:
- name: web
protocol: TCP
port: 8000
selector:
app: {{.AppName}}{{ end }}{{ if .NeedIngress}}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{.AppName}}-ingress
namespace: <PROJECT>-<GROUP>
labels:
app: {{.AppName}}
annotations:
nginx.ingress.kubernetes.io/use-regex: 'true'
spec:
rules:
- host: <HOST>
http:
paths:
- path: /{{.AppName}}.*
pathType: Prefix
backend:
service:
name: {{.AppName}}
port:
number: 8000{{ end }}`

type data struct {
AppName string
NeedService bool
NeedIngress bool
}

func CreatePathAndFile(appname string, needservice bool, needingress bool) {
dockerfile, e := os.OpenFile("./Dockerfile", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic("open ./Dockerfile error: " + e.Error())
}
if _, e := dockerfile.WriteString(docker); e != nil {
panic("write ./Dockerfile error: " + e.Error())
}
if e := dockerfile.Sync(); e != nil {
panic("sync ./Dockerfile error: " + e.Error())
}
if e := dockerfile.Close(); e != nil {
panic("close ./Dockerfile error: " + e.Error())
}

tmp := &data{
AppName: appname,
NeedService: needservice,
NeedIngress: needingress,
}
deploymenttemplate, e := template.New("./deployment.yaml").Parse(deployment)
if e != nil {
panic("parse ./deployment.yaml template error: " + e.Error())
}
kubernetesfile, e := os.OpenFile("./deployment.yaml", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if e != nil {
panic("open ./deployment.yaml error: " + e.Error())
}
if e := deploymenttemplate.Execute(kubernetesfile, tmp); e != nil {
panic("write ./deployment.yaml error: " + e.Error())
}
if e := kubernetesfile.Sync(); e != nil {
panic("sync ./deployment.yaml error: " + e.Error())
}
if e := kubernetesfile.Close(); e != nil {
panic("close ./deployment.yaml error: " + e.Error())
}
}
Loading