A very experimental PLC implementation which uses BFT consensus for decentralization

Enable pprof routes depending on config

gbl08ma.com ea37a472 3abd7c5f

verified
+35 -29
+4
config.go
··· 18 18 type PLCConfig struct { 19 19 // Address to listen for incoming connections 20 20 ListenAddress string `mapstructure:"laddr"` 21 + 22 + // Whether to expose pprof endpoints for debugging 23 + Pprof bool `mapstructure:"pprof"` 21 24 } 22 25 23 26 func DefaultPLCConfig() *PLCConfig { 24 27 return &PLCConfig{ 25 28 ListenAddress: "tcp://127.0.0.1:28080", 29 + Pprof: true, // TODO set to false once we move past alpha phase 26 30 } 27 31 }
+16 -14
httpapi/server.go
··· 61 61 mempoolSubmitter types.MempoolSubmitter, 62 62 nodeEventBus *cmttypes.EventBus, 63 63 listenAddr string, 64 - handlerTimeout time.Duration) (*Server, error) { 64 + handlerTimeout time.Duration, 65 + pprofEnabled bool) (*Server, error) { 65 66 s := &Server{ 66 67 logger: logger, 67 68 txFactory: txFactory, ··· 72 73 srv: http.Server{Addr: listenAddr}, 73 74 handlerTimeout: handlerTimeout, 74 75 } 75 - s.setupRoutes() 76 + s.setupRoutes(pprofEnabled) 76 77 77 78 handler := cors.Default().Handler(s.router) 78 79 ··· 91 92 } 92 93 93 94 // setupRoutes configures the routes for the server. 94 - func (s *Server) setupRoutes() { 95 + func (s *Server) setupRoutes(pprofEnabled bool) { 95 96 wrapInTimeout := func(fn http.HandlerFunc) http.Handler { 96 97 timeoutMsg, _ := json.Marshal(map[string]string{"message": "Internal server timeout"}) 97 98 ··· 106 107 s.router.Handle("GET /export", wrapInTimeout(s.handleExport)) 107 108 s.router.HandleFunc("/export/stream", s.handleExportStream) 108 109 109 - // TODO expose pprof only if enabled in [plc] settings 110 - s.router.HandleFunc("/debug/pprof/", pprof.Index) 111 - s.router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) 112 - s.router.HandleFunc("/debug/pprof/profile", pprof.Profile) 113 - s.router.HandleFunc("/debug/pprof/symbol", pprof.Symbol) 114 - s.router.HandleFunc("/debug/pprof/trace", pprof.Trace) 110 + if pprofEnabled { 111 + s.router.HandleFunc("/debug/pprof/", pprof.Index) 112 + s.router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) 113 + s.router.HandleFunc("/debug/pprof/profile", pprof.Profile) 114 + s.router.HandleFunc("/debug/pprof/symbol", pprof.Symbol) 115 + s.router.HandleFunc("/debug/pprof/trace", pprof.Trace) 115 116 116 - // Register handlers for specific profiles 117 - s.router.Handle("/debug/pprof/heap", pprof.Handler("heap")) 118 - s.router.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine")) 119 - s.router.Handle("/debug/pprof/block", pprof.Handler("block")) 120 - s.router.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate")) 117 + // Register handlers for specific profiles 118 + s.router.Handle("/debug/pprof/heap", pprof.Handler("heap")) 119 + s.router.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine")) 120 + s.router.Handle("/debug/pprof/block", pprof.Handler("block")) 121 + s.router.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate")) 122 + } 121 123 } 122 124 123 125 // makeDIDHandler creates a wrapper handler that extracts DID from URL path
+14 -14
httpapi/server_test.go
··· 111 111 txFactory, _, _ := testutil.NewTestTxFactory(t) 112 112 113 113 t.Run("Test Resolve DID", func(t *testing.T) { 114 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 114 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 115 115 require.NoError(t, err) 116 116 117 117 req, err := http.NewRequest("GET", "/did:plc:test", nil) ··· 126 126 127 127 t.Run("Test Resolve DID Not Found", func(t *testing.T) { 128 128 mockPLC := &MockReadPLC{shouldReturnError: true, errorType: "notfound"} 129 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 129 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 130 130 require.NoError(t, err) 131 131 132 132 req, err := http.NewRequest("GET", "/did:plc:test", nil) ··· 141 141 142 142 t.Run("Test Resolve DID Gone", func(t *testing.T) { 143 143 mockPLC := &MockReadPLC{shouldReturnError: true, errorType: "gone"} 144 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 144 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 145 145 require.NoError(t, err) 146 146 147 147 req, err := http.NewRequest("GET", "/did:plc:test", nil) ··· 156 156 157 157 t.Run("Test Resolve DID Internal Error", func(t *testing.T) { 158 158 mockPLC := &MockReadPLC{shouldReturnError: true, errorType: "internal"} 159 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 159 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 160 160 require.NoError(t, err) 161 161 162 162 req, err := http.NewRequest("GET", "/did:plc:test", nil) ··· 170 170 }) 171 171 172 172 t.Run("Test Create PLC Operation", func(t *testing.T) { 173 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 173 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 174 174 require.NoError(t, err) 175 175 176 176 op := map[string]interface{}{ ··· 194 194 }) 195 195 196 196 t.Run("Test Get PLC Log", func(t *testing.T) { 197 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 197 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 198 198 require.NoError(t, err) 199 199 200 200 req, err := http.NewRequest("GET", "/did:plc:test/log", nil) ··· 208 208 209 209 t.Run("Test Get PLC Log Not Found", func(t *testing.T) { 210 210 mockPLC := &MockReadPLC{shouldReturnError: true, errorType: "notfound"} 211 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 211 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 212 212 require.NoError(t, err) 213 213 214 214 req, err := http.NewRequest("GET", "/did:plc:test/log", nil) ··· 222 222 }) 223 223 224 224 t.Run("Test Get PLC Audit Log", func(t *testing.T) { 225 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 225 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 226 226 require.NoError(t, err) 227 227 228 228 req, err := http.NewRequest("GET", "/did:plc:test/log/audit", nil) ··· 235 235 }) 236 236 237 237 t.Run("Test Get Last Operation", func(t *testing.T) { 238 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 238 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 239 239 require.NoError(t, err) 240 240 241 241 req, err := http.NewRequest("GET", "/did:plc:test/log/last", nil) ··· 249 249 250 250 t.Run("Test Get Last Operation Internal Error", func(t *testing.T) { 251 251 mockPLC := &MockReadPLC{shouldReturnError: true, errorType: "internal"} 252 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 252 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 253 253 require.NoError(t, err) 254 254 255 255 req, err := http.NewRequest("GET", "/did:plc:test/log/last", nil) ··· 263 263 }) 264 264 265 265 t.Run("Test Get PLC Data", func(t *testing.T) { 266 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 266 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 267 267 require.NoError(t, err) 268 268 269 269 req, err := http.NewRequest("GET", "/did:plc:test/data", nil) ··· 277 277 278 278 t.Run("Test Get PLC Data Not Found", func(t *testing.T) { 279 279 mockPLC := &MockReadPLC{shouldReturnError: true, errorType: "notfound"} 280 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 280 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 281 281 require.NoError(t, err) 282 282 283 283 req, err := http.NewRequest("GET", "/did:plc:test/data", nil) ··· 291 291 }) 292 292 293 293 t.Run("Test Export", func(t *testing.T) { 294 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 294 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 295 295 require.NoError(t, err) 296 296 297 297 req, err := http.NewRequest("GET", "/export?count=10", nil) ··· 305 305 306 306 t.Run("Test Export Internal Error", func(t *testing.T) { 307 307 mockPLC := &MockReadPLC{shouldReturnError: true, errorType: "internal"} 308 - server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second) 308 + server, err := NewServer(testLogger, txFactory, mockPLC, nil, nil, "tcp://127.0.0.1:8080", 15*time.Second, false) 309 309 require.NoError(t, err) 310 310 311 311 req, err := http.NewRequest("GET", "/export?count=10", nil)
+1 -1
main.go
··· 215 215 }() 216 216 217 217 if config.PLC.ListenAddress != "" { 218 - plcAPIServer, err := httpapi.NewServer(logger.With("module", "plcapi"), txFactory, plc, mempoolSubmitter, node.EventBus(), config.PLC.ListenAddress, 10*time.Second) 218 + plcAPIServer, err := httpapi.NewServer(logger.With("module", "plcapi"), txFactory, plc, mempoolSubmitter, node.EventBus(), config.PLC.ListenAddress, 10*time.Second, config.PLC.Pprof) 219 219 if err != nil { 220 220 log.Fatalf("Creating PLC API server: %v", err) 221 221 }