@Override
    @MustBeClosed
    default SafeCloseable push() {
        final RequestContext oldCtx = RequestContextUtil.getAndSet(this);
        if (oldCtx == null) {
            return RequestContextUtil.invokeHookAndPop(this, null);
        }

        if (oldCtx.unwrapAll() == unwrapAll()) {
            // Reentrance, invoke only the hooks because some new hooks may have been added after the last push.
            final SafeCloseable closeable = invokeHook(this);
            return firstNonNull(closeable, noopSafeCloseable());
        }

        if (RequestContextUtil.equalsIgnoreWrapper(oldCtx.root(), this)) {
            return RequestContextUtil.invokeHookAndPop(this, oldCtx);
        }

        // Put the oldCtx back before throwing an exception.
        RequestContextUtil.pop(this, oldCtx);
        throw newIllegalContextPushingException(this, oldCtx);
    }
Pushes this context to the thread-local stack. To pop the context from the stack, call
{@link SafeCloseable#close()}, which can be done using a {@code try-with-resources} block:
<pre>{@code
try (SafeCloseable ignored = ctx.push()) {
    ...
}
}</pre>

<p>In order to call this method, the current thread-local state must meet one of the
following conditions:
<ul>
  <li>the thread-local does not have any {@link RequestContext} in it</li>
  <li>the thread-local has the same {@link ServiceRequestContext} as this - reentrance</li>
  <li>the thread-local has the {@link ClientRequestContext} whose {@link ClientRequestContext#root()}
      is the same {@link ServiceRequestContext} as this</li>
</ul>
Otherwise, this method will throw an {@link IllegalStateException}.
core/src/main/java/com/linecorp/armeria/server/ServiceRequestContext.java