Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: arbitrary function call from HTTP debug server #85

Open
xhd2015 opened this issue Apr 23, 2024 · 6 comments
Open

Feature: arbitrary function call from HTTP debug server #85

xhd2015 opened this issue Apr 23, 2024 · 6 comments

Comments

@xhd2015
Copy link
Owner

xhd2015 commented Apr 23, 2024

The problem is: is it possible to call arbitrary function through http without modifying any code?

The answer is: it is possible, and could be a major feature of xgo. Because package runtime/functab already have all registered func informations, so we can call them.

This could be a standalone usage apart from trap, mock and trace.

@xhd2015
Copy link
Owner Author

xhd2015 commented Apr 23, 2024

The reasons this is being useful:

  • Debug the function without any code modification
  • Collect the stack trace and visualize it

@WAY29
Copy link

WAY29 commented Apr 24, 2024

I'm interested in this. Can you introduce the implementation principle and a fast poc about usage?

@xhd2015
Copy link
Owner Author

xhd2015 commented Apr 24, 2024

I'm interested in this. Can you introduce the implementation principle and a fast poc about usage?

@WAY29 Huh thanks for replying. This has been adopted inside my team. Actually, the whole xgo is an open source equivalent of a library we're using from day to day internally.

Brief Design

Brief design overview for this functionality:

  • If build main with xgo build --debug-server,xgo will inject a init_debug_server.go alongside with main.go
  • The init_debug_server.go will start a new goroutine that serves an http listener on port 45000
  • That server handles request to /debug/invoke with the following param:
type InvokeFuncRequest struct {
	Pkg         string `json:"pkg"`
	Func       string `json:"func"`
	MockData    *MockData `json:"mockData"` // this is yet to be discussed 
	Request    json.RawMessage `json:"request"`
}
  • And response with:
type InvokeFuncResponse struct {
	Response    interface{}              `json:"response,omitempty"`
	Error           string                   `json:"error"`
	StackTrace  json.RawMessage`json:"stackTrace"`
}
  • The response can then be visualized by xgo tool trace

Usage example

Assuming user have a go project like this:

main.go
service/
   greet.go
go.mod

service/greet.go has a function Greet:

func Greet(s string) string {
    return "hello " + s
}

Typical usage from the user side:

$ xgo run --debug-server .
Debug server listens at http://localhost:45000

$ curl localhost:45000/debug/invoke -H 'Content-Type: application/json' --data '{"pkg":"./service", "func":"Greet", "request":{"s":"world"}}'
# Browser will automatically open to show the trace
hello world

Real usage

This is an example from our live-canary environment, the live-canary environment is the same as live environment except it's traffic is rather small, about 1/1000 of the live.

This tool helps debugging a lot.

image

@xhd2015 xhd2015 added the testing label May 9, 2024
@xhd2015
Copy link
Owner Author

xhd2015 commented May 9, 2024

Design brief:

  1. build/run with --debug-server: xgo run --debug-server. NOTE: --debug-server not available in test mode

--debug-server options:
without any extra options, listen at port 45000.
can specify other options like filtering...
2. Then , with default route as /debug, user can view the debug page when opening http://localhost:45000/debug

Also allow attach to an existing http server programmatically:

package main

import "github.com/xhd2015/xgo/runtime/debug"

func Init(mux *http.ServeMux){
     // will add three sub routes: /testing, /testing/listFunc, /testing/invokeFunc
     // user can view the debug page when opening http://localhost:PORT/testing 
    debug.AttachHandlers(mux,"/testing", ...options...)
}

@xhd2015
Copy link
Owner Author

xhd2015 commented May 9, 2024

Xgo's principal when providing tools: no invading the source code, so it becomes completely optional, people can choose to opt in or out any any time they want. No enforcement.

@xhd2015 xhd2015 changed the title Discussion: is it possible to call arbitrary function through http without modifying any code? Feature: arbitrary function call from HTTP debug server May 18, 2024
@xhd2015
Copy link
Owner Author

xhd2015 commented May 18, 2024

General input/output follow the function's arg and result name. Special cases are:

  • When there is only one paramater or a parameter with a context, treat the whole request for that sole parameter
  • When there is only one result, or result with an error, treat the result as the whole response

@xhd2015 xhd2015 added this to the v1.1.0 milestone May 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests

2 participants