Skip to content

Instantly share code, notes, and snippets.

@andytill
Last active March 14, 2017 16:07
Show Gist options
  • Save andytill/c636eec91d11c28a201c1d1312a10431 to your computer and use it in GitHub Desktop.
Save andytill/c636eec91d11c28a201c1d1312a10431 to your computer and use it in GitHub Desktop.
Replace or Modify Process State

Given a process state using the following record, how could we modify one of the record fields?

-record(state, {
          status :: init_in_progress | {init_failed, Reason::term()} | ready,
          qbufs = [] :: [{qbuf_ref(), #qbuf{}}],
          qbuf_serial_id = 0 :: non_neg_integer(),
          total_size = 0 :: non_neg_integer(),
          %% no new queries; accumulation allowed
          soft_watermark :: non_neg_integer(),
          %% drop some tables now
          hard_watermark :: non_neg_integer(),
          %% process heap size limit before forcing dumping in-mem buffer to ldb
          inmem_max :: non_neg_integer(),
          %% drop incomplete query buffer after this long since last add_chunk
          incomplete_qbuf_release_msec :: non_neg_integer(),
          %% drop complete query buffers after this long since serving last query
          qbuf_expire_msec :: non_neg_integer(),
          %% max query size
          max_query_data_size :: non_neg_integer(),
          %% dir containing qbuf ldb files
          root_path :: string()
}).

sys:replace_state/2 allows us to replace process state from an attached shell. To replace a field of an element we can use the snippet below. All that is needed is the pid or registered name of the process and the index of the field. To find the index, count to the field (base one) and add one because the record name is the first element.

sys:replace_state(riak_kv_qry_buffers, fun(State) -> erlang:setelement(8,State,2048) end).

This modifies the 8th element of the record, inmem_max and sets it to 2048. This is how it looks in the shell.

(dev1@127.0.0.1)2> sys:replace_state(riak_kv_qry_buffers, fun(State) -> erlang:setelement(8,State,2048) end).
{state,ready,[],7,0,1073741824,4294967296,2048,9000,0,
       10000000,"./data/query_buffers"}

This is great for testing where you may want to try different values without restarting a node.

@aboroska
Copy link

#state.inmem_max can be used instead of 8.

@aboroska
Copy link

Of course you need to load the record definitions by rr(Module) first in the shell. Then #state.inmem_max will be equal to 8.

@andytill
Copy link
Author

True, I always forget about the record functions in the shell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment