|
- package chinamobile_seedance
-
- import (
- "fmt"
- "strings"
- "sync"
- "time"
-
- maas "maas_seedance_sdk_1.0.0_go"
- )
-
- const (
- defaultBaseURL = "https://zhenze-huhehaote.cmecloud.cn/api/v3"
- defaultModel = "doubao-seedance-2.0"
- defaultSubmitTimeout = 180 * time.Second
- defaultQueryTimeout = 60 * time.Second
- sdkAcquireTimeout = 2 * time.Second
- )
-
- var sdkSemaphore = make(chan struct{}, 4)
-
- type seedanceSDK interface {
- CreateVideoGenerationTask(data map[string]interface{}) (string, error)
- QueryVideoGenerationTask(taskID string) (map[string]interface{}, error)
- }
-
- type seedanceSDKFactory func(baseURL, apiKey, model string) (seedanceSDK, error)
-
- func newRealSDK(baseURL, apiKey, model string) (seedanceSDK, error) {
- baseURL = strings.TrimRight(strings.TrimSpace(baseURL), "/")
- if baseURL == "" {
- baseURL = defaultBaseURL
- }
- model = strings.TrimSpace(model)
- if model == "" {
- model = defaultModel
- }
- return runSDKCall[seedanceSDK](defaultQueryTimeout, func() (seedanceSDK, error) {
- return maas.NewMaasSeedanceClient(baseURL, apiKey, model, false)
- })
- }
-
- func runSDKCall[T any](timeout time.Duration, fn func() (T, error)) (T, error) {
- var zero T
- select {
- case sdkSemaphore <- struct{}{}:
- case <-time.After(sdkAcquireTimeout):
- return zero, fmt.Errorf("upstream_busy: sdk concurrency limit reached")
- }
-
- type result struct {
- value T
- err error
- }
- var releaseOnce sync.Once
- release := func() {
- releaseOnce.Do(func() {
- <-sdkSemaphore
- })
- }
- done := make(chan result, 1)
- go func() {
- res := result{}
- defer func() {
- if r := recover(); r != nil {
- res.err = fmt.Errorf("upstream_sdk_panic: %v", r)
- }
- release()
- done <- res
- }()
- res.value, res.err = fn()
- }()
-
- select {
- case res := <-done:
- return res.value, res.err
- case <-time.After(timeout):
- release()
- return zero, fmt.Errorf("upstream_timeout: sdk call exceeded %s", timeout)
- }
- }
|