-
Notifications
You must be signed in to change notification settings - Fork 174
feat: add probing service and update mobile adapter #652
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,10 +24,9 @@ import "unsafe" | |
| import "fmt" | ||
| import "runtime" | ||
|
|
||
|
|
||
| type Session struct { | ||
| cHandle C.MllmCAny | ||
| sessionID string | ||
| cHandle C.MllmCAny | ||
| sessionID string | ||
| } | ||
|
|
||
| func isOk(any C.MllmCAny) bool { | ||
|
|
@@ -43,103 +42,122 @@ func ShutdownContext() bool { | |
| } | ||
|
|
||
| func StartService(workerThreads int) bool { | ||
| result := C.startService(C.size_t(workerThreads)) | ||
| return isOk(result) | ||
| result := C.startService(C.size_t(workerThreads)) | ||
| return isOk(result) | ||
| } | ||
|
|
||
| func StopService() bool { | ||
| result := C.stopService() | ||
| return isOk(result) | ||
| result := C.stopService() | ||
| return isOk(result) | ||
| } | ||
|
|
||
| func SetLogLevel(level int) { | ||
| C.setLogLevel(C.int(level)) | ||
| C.setLogLevel(C.int(level)) | ||
| } | ||
|
|
||
| func NewSession(modelPath string) (*Session, error) { | ||
| cModelPath := C.CString(modelPath) | ||
| defer C.free(unsafe.Pointer(cModelPath)) | ||
| cModelPath := C.CString(modelPath) | ||
| defer C.free(unsafe.Pointer(cModelPath)) | ||
|
|
||
| handle := C.createQwen3Session(cModelPath) | ||
| if !isOk(handle) { | ||
| return nil, fmt.Errorf("底层C API createQwen3Session 失败") | ||
| } | ||
| s := &Session{cHandle: handle} | ||
| runtime.SetFinalizer(s, func(s *Session) { | ||
| fmt.Println("[Go Finalizer] Mllm Session automatically released.") | ||
| C.freeSession(s.cHandle) | ||
| }) | ||
|
|
||
| return s, nil | ||
| } | ||
|
|
||
| func NewProbingSession(modelPath string, probePath string) (*Session, error) { | ||
| cModelPath := C.CString(modelPath) | ||
| defer C.free(unsafe.Pointer(cModelPath)) | ||
| cProbePath := C.CString(probePath) | ||
| defer C.free(unsafe.Pointer(cProbePath)) | ||
|
|
||
| handle := C.createQwen3Session(cModelPath) | ||
| if !isOk(handle) { | ||
| return nil, fmt.Errorf("底层C API createQwen3Session 失败") | ||
| } | ||
| s := &Session{cHandle: handle} | ||
| runtime.SetFinalizer(s, func(s *Session) { | ||
| fmt.Println("[Go Finalizer] Mllm Session automatically released.") | ||
| C.freeSession(s.cHandle) | ||
| }) | ||
| handle := C.createQwen3ProbingSession(cModelPath, cProbePath) | ||
| if !isOk(handle) { | ||
| return nil, fmt.Errorf("底层C API createQwen3ProbingSession 失败") | ||
| } | ||
| s := &Session{cHandle: handle} | ||
| runtime.SetFinalizer(s, func(s *Session) { | ||
| fmt.Println("[Go Finalizer] Mllm Probing Session automatically released.") | ||
| C.freeSession(s.cHandle) | ||
| }) | ||
|
|
||
| return s, nil | ||
| return s, nil | ||
| } | ||
|
|
||
| func NewDeepseekOCRSession(modelPath string) (*Session, error) { | ||
| cModelPath := C.CString(modelPath) | ||
| defer C.free(unsafe.Pointer(cModelPath)) | ||
| cModelPath := C.CString(modelPath) | ||
| defer C.free(unsafe.Pointer(cModelPath)) | ||
|
|
||
| handle := C.createDeepseekOCRSession(cModelPath) | ||
| if !isOk(handle) { | ||
| return nil, fmt.Errorf("底层C API createDeepseekOCRSession 失败") | ||
| } | ||
| s := &Session{cHandle: handle} | ||
| runtime.SetFinalizer(s, func(s *Session) { | ||
| fmt.Println("[Go Finalizer] Mllm OCR Session automatically released.") | ||
| C.freeSession(s.cHandle) | ||
| }) | ||
| handle := C.createDeepseekOCRSession(cModelPath) | ||
| if !isOk(handle) { | ||
| return nil, fmt.Errorf("底层C API createDeepseekOCRSession 失败") | ||
| } | ||
| s := &Session{cHandle: handle} | ||
| runtime.SetFinalizer(s, func(s *Session) { | ||
| fmt.Println("[Go Finalizer] Mllm OCR Session automatically released.") | ||
| C.freeSession(s.cHandle) | ||
| }) | ||
|
|
||
| return s, nil | ||
| return s, nil | ||
| } | ||
|
|
||
| func (s *Session) Close() { | ||
| if C.MllmCAny_get_v_custom_ptr(s.cHandle) != nil { | ||
| fmt.Println("[Go Close] Mllm Session manually closed.") | ||
| C.freeSession(s.cHandle) | ||
| s.cHandle = C.MllmCAny_set_v_custom_ptr_null(s.cHandle) | ||
| runtime.SetFinalizer(s, nil) | ||
| } | ||
| if C.MllmCAny_get_v_custom_ptr(s.cHandle) != nil { | ||
| fmt.Println("[Go Close] Mllm Session manually closed.") | ||
| C.freeSession(s.cHandle) | ||
| s.cHandle = C.MllmCAny_set_v_custom_ptr_null(s.cHandle) | ||
| runtime.SetFinalizer(s, nil) | ||
| } | ||
|
Comment on lines
111
to
+117
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Check if the file exists and read the Close() function
find . -name "c.go" -path "*mllm-cli*" | head -5Repository: UbiquitousLearning/mllm Length of output: 87 🏁 Script executed: # Read the specific lines from the file
sed -n '105,120p' ./mllm-cli/mllm/c.goRepository: UbiquitousLearning/mllm Length of output: 426 🏁 Script executed: # Check if Close() is used in deferred/cleanup contexts
rg "defer.*\.Close\(\)" ./mllm-cli --type go -A 2 -B 2 | head -30Repository: UbiquitousLearning/mllm Length of output: 291 🏁 Script executed: # Search for Session.Close() usage patterns
rg "Session.*Close\(\)" ./mllm-cli --type go -B 3 -A 2 | head -50Repository: UbiquitousLearning/mllm Length of output: 348 🏁 Script executed: # Check where Close() is actually called or if it's used as a callback
rg "\.Close" ./mllm-cli/mllm --type go -B 2 -A 2Repository: UbiquitousLearning/mllm Length of output: 49 🏁 Script executed: # Broader search for Close usage in mllm-cli
rg "Close" ./mllm-cli --type go | head -20Repository: UbiquitousLearning/mllm Length of output: 738 🏁 Script executed: # Check the actual calls to session.Close() in the service and main files
rg -B 5 -A 2 "session\.Close\(\)" ./mllm-cli --type goRepository: UbiquitousLearning/mllm Length of output: 1612 Add nil-safety check to The function dereferences Proposed fix func (s *Session) Close() {
+ if s == nil {
+ return
+ }
if C.MllmCAny_get_v_custom_ptr(s.cHandle) != nil {
fmt.Println("[Go Close] Mllm Session manually closed.")
C.freeSession(s.cHandle)
s.cHandle = C.MllmCAny_set_v_custom_ptr_null(s.cHandle)
runtime.SetFinalizer(s, nil)
}
}🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| func (s *Session) Insert(sessionID string) bool { | ||
| cSessionID := C.CString(sessionID) | ||
| defer C.free(unsafe.Pointer(cSessionID)) | ||
| result := C.insertSession(cSessionID, s.cHandle) | ||
| if isOk(result) { | ||
| s.sessionID = sessionID | ||
| } | ||
| return isOk(result) | ||
| cSessionID := C.CString(sessionID) | ||
| defer C.free(unsafe.Pointer(cSessionID)) | ||
| result := C.insertSession(cSessionID, s.cHandle) | ||
| if isOk(result) { | ||
| s.sessionID = sessionID | ||
| } | ||
| return isOk(result) | ||
| } | ||
|
|
||
| func (s *Session) SendRequest(jsonRequest string) bool { | ||
| if s.sessionID == "" { | ||
| fmt.Println("[Go SendRequest] Error: sessionID is not set on this session.") | ||
| return false | ||
| } | ||
| cSessionID := C.CString(s.sessionID) | ||
| cJsonRequest := C.CString(jsonRequest) | ||
| defer C.free(unsafe.Pointer(cSessionID)) | ||
| defer C.free(unsafe.Pointer(cJsonRequest)) | ||
|
|
||
| result := C.sendRequest(cSessionID, cJsonRequest) | ||
| return isOk(result) | ||
| } | ||
|
|
||
| func (s *Session) PollResponse(requestID string) string { | ||
| if requestID == "" { | ||
| fmt.Println("[Go PollResponse] Error: requestID cannot be empty.") | ||
| return "" | ||
| } | ||
| cRequestID := C.CString(requestID) | ||
| defer C.free(unsafe.Pointer(cRequestID)) | ||
|
|
||
| cResponse := C.pollResponse(cRequestID) | ||
| if cResponse == nil { | ||
| return "" | ||
| } | ||
| defer C.freeResponseString(cResponse) | ||
| return C.GoString(cResponse) | ||
| if s.sessionID == "" { | ||
| fmt.Println("[Go SendRequest] Error: sessionID is not set on this session.") | ||
| return false | ||
| } | ||
| cSessionID := C.CString(s.sessionID) | ||
| cJsonRequest := C.CString(jsonRequest) | ||
| defer C.free(unsafe.Pointer(cSessionID)) | ||
| defer C.free(unsafe.Pointer(cJsonRequest)) | ||
|
|
||
| result := C.sendRequest(cSessionID, cJsonRequest) | ||
| return isOk(result) | ||
| } | ||
|
|
||
| func (s *Session) PollResponse(requestID string) string { | ||
| if requestID == "" { | ||
| fmt.Println("[Go PollResponse] Error: requestID cannot be empty.") | ||
| return "" | ||
| } | ||
| cRequestID := C.CString(requestID) | ||
| defer C.free(unsafe.Pointer(cRequestID)) | ||
|
|
||
| cResponse := C.pollResponse(cRequestID) | ||
| if cResponse == nil { | ||
| return "" | ||
| } | ||
| defer C.freeResponseString(cResponse) | ||
|
|
||
| return C.GoString(cResponse) | ||
| } | ||
|
|
||
| func (s *Session) SessionID() string { | ||
| return s.sessionID | ||
| return s.sessionID | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: UbiquitousLearning/mllm
Length of output: 1586
Add defensive check for negative
workerThreadsparameter.The function parameter accepts
int, which can be negative. While all current callers (inmain.goandmobile_server.go) pass the literal value1, a defensive check would prevent accidental misuse if the API is called with untrusted input in the future.💡 Suggested improvement
func StartService(workerThreads int) bool { + if workerThreads <= 0 { + return false + } result := C.startService(C.size_t(workerThreads)) return isOk(result) }📝 Committable suggestion
🤖 Prompt for AI Agents