Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ You can load a JSON configuration such as:
}
```

Or use the poke strategy to start instances without waiting:

```json
{
"sablier_url": "sablier:10000",
"group": "my-group",
"session_duration": "1m",
"poke": {}
}
```

## Examples

### Apache APISIX
Expand Down
36 changes: 32 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type pluginConfiguration struct {
path string
authority string
timeout uint32
poke bool
}

// newPluginConfiguration creates a pluginConfiguration with default values
Expand Down Expand Up @@ -91,6 +92,9 @@ type BlockingConfiguration struct {
Timeout string `json:"timeout"`
}

type PokeConfiguration struct {
}

type Config struct {
// SablierURL in the format of hostname:port. The scheme is excluded
SablierURL string `json:"sablier_url"`
Expand All @@ -105,6 +109,7 @@ type Config struct {
SessionDuration string `json:"session_duration"`
Dynamic *DynamicConfiguration `json:"dynamic"`
Blocking *BlockingConfiguration `json:"blocking"`
Poke *PokeConfiguration `json:"poke"`
}

func (c Config) GetPath() string {
Expand Down Expand Up @@ -133,6 +138,8 @@ func (c Config) GetPath() string {
return c.getDynamicQuery(path)
} else if c.Blocking != nil {
return c.getBlockingQuery(path)
} else if c.Poke != nil {
return c.getPokeQuery(path)
}
return "no strategy configured"
}
Expand Down Expand Up @@ -183,6 +190,12 @@ func (c Config) getBlockingQuery(path url.URL) string {
return path.String()
}

func (c Config) getPokeQuery(path url.URL) string {
path.Path = "/api/strategies/poke"

return path.String()
}

func parsePluginConfiguration(data []byte) (pluginConfiguration, error) {
pluginConf := newPluginConfiguration()
if len(data) == 0 {
Expand All @@ -196,11 +209,20 @@ func parsePluginConfiguration(data []byte) (pluginConfiguration, error) {
return pluginConf, err
}

if c.Blocking == nil && c.Dynamic == nil {
return pluginConf, fmt.Errorf("you must specify one strategy (dynamic or blocking)")
strategyCount := 0
if c.Blocking != nil {
strategyCount++
}

if c.Blocking != nil && c.Dynamic != nil {
if c.Dynamic != nil {
strategyCount++
}
if c.Poke != nil {
strategyCount++
}
if strategyCount == 0 {
return pluginConf, fmt.Errorf("you must specify one strategy (dynamic, blocking or poke)")
}
if strategyCount > 1 {
return pluginConf, fmt.Errorf("you must specify only one strategy")
}

Expand Down Expand Up @@ -232,6 +254,7 @@ func parsePluginConfiguration(data []byte) (pluginConfiguration, error) {
}

pluginConf.path = c.GetPath()
pluginConf.poke = c.Poke != nil

return pluginConf, nil
}
Expand All @@ -250,6 +273,7 @@ func (ctx *pluginContext) NewHttpContext(contextID uint32) types.HttpContext {
headers: headers,
cluster: ctx.configuration.cluster,
timeout: ctx.configuration.timeout,
poke: ctx.configuration.poke,
}
}

Expand All @@ -261,6 +285,7 @@ type httpOnDemand struct {
headers [][2]string
cluster string
timeout uint32
poke bool
}

// Override types.DefaultHttpContext.
Expand All @@ -276,6 +301,9 @@ func (ctx *httpOnDemand) OnHttpRequestHeaders(numHeaders int, endOfStream bool)

proxywasm.LogInfof("http call dispatched to %s", ctx.cluster)

if ctx.poke {
return types.ActionContinue
}
return types.ActionPause
}

Expand Down
21 changes: 21 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@ import (
"github.com/stretchr/testify/require"
)

func TestUnmarshalPoke(t *testing.T) {
data := `{
"sablier_url": "sablier",
"group": "demo",
"session_duration": "30s",
"poke": {}
}`

config, err := parsePluginConfiguration([]byte(data))
if err != nil {
t.Error(err)
}

expected := "/api/strategies/poke?group=demo&session_duration=30s"
if config.path != expected {
t.Errorf("path = %v, want %v", config.path, expected)
}

t.Log("path:", config.path)
}

func TestUnmarshal(t *testing.T) {
data := `{
"sablier_url": "sablier",
Expand Down