Skip to content

Commit

Permalink
Add new "--plaintext-metadata" flag.
Browse files Browse the repository at this point in the history
When this flag is used, we don't templatize metadata JSON object for
every single request and json load it, but we only do that once and
re-use cached version for subsequent requests.

This results in much less overhead when metadata template functionality
is not needed and utilizing large metadata objects.
  • Loading branch information
Kami committed Jan 6, 2021
1 parent f46a37e commit d586c35
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 14 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -86,6 +86,7 @@ Flags:
-B, --binary-file= File path for the call data as serialized binary message or multiple count-prefixed messages.
-m, --metadata= Request metadata as stringified JSON. Either as an object or an array of objects.
-M, --metadata-file= File path for call metadata JSON file. Examples: /home/user/metadata.json or ./metadata.json.
--plaintext-metadata True to not try to templatize the metadata object. This should be used when using large metadata obejects when template functionality is not used since it speeds things up.
--stream-interval=0 Interval for stream requests between message sends.
--reflect-metadata= Reflect metadata as stringified JSON used only for reflection request.
-o, --output= Output path. If none provided stdout is used.
Expand Down
9 changes: 9 additions & 0 deletions cmd/ghz/main.go
Expand Up @@ -130,6 +130,10 @@ var (
mdPath = kingpin.Flag("metadata-file", "File path for call metadata JSON file. Examples: /home/user/metadata.json or ./metadata.json.").
Short('M').PlaceHolder(" ").IsSetByUser(&isMDPathSet).String()

isPlainTextMetadataSet = false
plaintextMetadata = kingpin.Flag("plaintext-metadata", "Don't try to templatize metadata string for each request and used cached value for all the requests.").
Default("false").IsSetByUser(&isPlainTextMetadataSet).Bool()

isSISet = false
si = kingpin.Flag("stream-interval", "Interval for stream requests between message sends.").
Default("0").IsSetByUser(&isSISet).Duration()
Expand Down Expand Up @@ -394,6 +398,7 @@ func createConfigFromArgs(cfg *runner.Config) error {
cfg.BinDataPath = *binPath
cfg.Metadata = metadataArray
cfg.MetadataPath = *mdPath
cfg.PlaintextMetadata = *plaintextMetadata
cfg.SI = runner.Duration(*si)
cfg.Output = *output
cfg.Format = *format
Expand Down Expand Up @@ -512,6 +517,10 @@ func mergeConfig(dest *runner.Config, src *runner.Config) error {
dest.MetadataPath = src.MetadataPath
}

if isPlainTextMetadataSet {
dest.PlaintextMetadata = src.PlaintextMetadata
}

if isSISet {
dest.SI = src.SI
}
Expand Down
1 change: 1 addition & 0 deletions runner/config.go
Expand Up @@ -82,6 +82,7 @@ type Config struct {
BinDataPath string `json:"binary-file" toml:"binary-file" yaml:"binary-file"`
Metadata interface{} `json:"metadata,omitempty" toml:"metadata,omitempty" yaml:"metadata,omitempty"`
MetadataPath string `json:"metadata-file" toml:"metadata-file" yaml:"metadata-file"`
PlaintextMetadata bool `json:"plaintextMetadata" toml:"plaintextMetadata" yaml:"PlaintextMetadata"`
SI Duration `json:"stream-interval" toml:"stream-interval" yaml:"stream-interval"`
Output string `json:"output" toml:"output" yaml:"output"`
Format string `json:"format" toml:"format" yaml:"format" default:"summary"`
Expand Down
19 changes: 15 additions & 4 deletions runner/options.go
Expand Up @@ -58,10 +58,11 @@ type RunConfig struct {
streamInterval time.Duration

// data
data []byte
binary bool
metadata []byte
rmd map[string]string
data []byte
binary bool
metadata []byte
PlaintextMetadata bool
rmd map[string]string

// debug
hasLog bool
Expand Down Expand Up @@ -435,6 +436,15 @@ func WithMetadataFromFile(path string) Option {
}
}

// WithPlaintextMetadata to not utilize metadata templating functionality
func WithPlaintextMetadata(value bool) Option {
return func(o *RunConfig) error {
o.PlaintextMetadata = value

return nil
}
}

// WithName sets the name of the test run
// WithName("greeter service test")
func WithName(name string) Option {
Expand Down Expand Up @@ -725,6 +735,7 @@ func fromConfig(cfg *Config) []Option {
WithName(cfg.Name),
WithCPUs(cfg.CPUs),
WithMetadata(cfg.Metadata),
WithPlaintextMetadata(cfg.PlaintextMetadata),
WithTags(cfg.Tags),
WithStreamInterval(time.Duration(cfg.SI)),
WithReflectionMetadata(cfg.ReflectMetadata),
Expand Down
33 changes: 23 additions & 10 deletions runner/worker.go
Expand Up @@ -32,6 +32,10 @@ type Worker struct {
// cached messages only for binary
cachedMessages []*dynamic.Message

// cached metadata array for situations where metadata templating
// functionality is not used
cachedReqMDs []metadata.MD

// non-binary json optimization
arrayJSONData []string
}
Expand Down Expand Up @@ -82,19 +86,28 @@ func (w *Worker) makeRequest() error {
}
}

mdArray, err := ctd.executeMetadataArray(string(w.config.metadata))
if err != nil {
return err
}

var reqMDs []metadata.MD

if len(mdArray) > 0 {
for _, mdItem := range mdArray {
reqMDs = append(reqMDs, metadata.New(mdItem))
}
if w.cachedReqMDs != nil {
// If templating is not used and cached metadata is available, we use this
// array. This way we avoid rendering and json loading potentially very
// large metadata object for every single request
reqMDs = w.cachedReqMDs
} else {
reqMDs = append(reqMDs, metadata.MD{})
mdArray, err := ctd.executeMetadataArray(string(w.config.metadata))
if err != nil {
return err
}

if len(mdArray) > 0 {
for _, mdItem := range mdArray {
reqMDs = append(reqMDs, metadata.New(mdItem))
}
} else {
reqMDs = append(reqMDs, metadata.MD{})
}

w.cachedReqMDs = reqMDs
}

metadatasLen := len(reqMDs)
Expand Down
7 changes: 7 additions & 0 deletions www/docs/examples.md
Expand Up @@ -95,9 +95,16 @@ ghz --insecure \
--call helloworld.Greeter.SayHello \
-d '[{"name":"Joe"},{"name":"Bob"}]' \
-m '[{"item one":"value 1"},{"item two":"value 2"}]' \
--plaintext-metadata \
0.0.0.0:50051
```

If you are using large metadata array and don't rely on template functionality in metadata
JSON string, you should also use ``--plaintext-metadata`` as shown above.

This will cause the code to skip rendering the metadata item as a template for every single
RPC request and will speed things up.

<a name="custom-parameters">
### Custom parameters

Expand Down

0 comments on commit d586c35

Please sign in to comment.