Skip to content

Conversation

@ywkaras
Copy link
Contributor

@ywkaras ywkaras commented Aug 9, 2019

These classes may be used independently of other parts of the TS CPP API.

@ywkaras ywkaras force-pushed the cppapi_msg branch 2 times, most recently from 2d7a00a to 514e60a Compare August 10, 2019 00:51
@SolidWallOfCode
Copy link
Member

This code might be interesting to look at as a comparison.

~MimeField();

private:
MsgBase &_msg;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to copy over the MBuffer and MLoc instead of carrying a reference. It's cheap to do and removes any scope dependencies between them. It's quite possible to envision logic that gets the field and passes it on after the base object has gone out of scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't envision logic where it would be desirable to have multiple copies of these. Especially given the problem that they may go stale if you carry them from one hook to another. I gave a link to an example in the comments showing that gcc is good at optimizing out references, even when they are class members.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to have copies than a hidden lifetime dependency. The copies are cheap. Going stale is the same issue in either case - I don't see why it matters if the staleness is via reference or copy. In both cases all instances need to have been cleaned up.

Consider code like

MimeField host;
if (some_flag) {
  HttpMsg msg = get_proxy_request();
  host = msg.findMimeField("Host");
} else {
  HttpMsg msg = get_proxy_response();
  host = msg.findMimeField("Host");
}
field.assign(pristine_host); // Woops, field depends on an out of scope object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even with copies, your example is problematic. My current design is that ~HttpMsg() releases the TMLoc for the message. If it's not done in the destructor, then where? Why not:

HttpMsg msgReq = get_proxy_request();
HttpMsg msgRes = get_proxy_response();
MimeField host = (some_flag ? msgReq : msgResp).findMimeField("Host");
host.assign(pristine_host);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each object tracks its own TSMLoc and releases it when destructed.

Your example could be simplified down to

MimeFile host = (some_flag ? get_proxy_request() : get_proxy_response()).findMimeField("Host");
host.assign(pristine_host);

Which causes the problem again. Certainly the reference style could be made to work, but it imposes additional very non-obvious requirements on how the classes can be used, for very little (if any) benefit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess what you're saying is that MimeField doesn't get its MBuffer and TSMLoc instances by a simple assign, it gets new values that refer to the same buffer and message header. What is the TS API call to get these new values? Is there a TS API call that can check that two distinct MBuffer/TSMLoc instances refer to the same object?

Certainly there are advantages to having pointers be shared_ptr or something similar (or using some other form of garbage collection). But it's not the C++ way to use this approach exclusively. Rightly or wrongly, the perception is that the CPP API is too high-overhead. So that argues against increasing overhead to make it perfectly ironclad.

Copy link
Contributor Author

@ywkaras ywkaras Aug 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you are making multiple simple copies of the TSMLoc for the message headers: https://github.com/SolidWallOfCode/txn_box/blob/03093bf02e46f092691afe70d7b3d87151b2953a/plugin/include/txn_box/ts_util.h#L116 . Seems like your are leaking them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK looking at TSHandleMLocRelease(), it doesn't actually do anything for message header mlocs (HDR_HEAP_OBJ_HTTP_HEADER), are you saying we should rely on that fact?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW (some_flag ? get_proxy_request() : get_proxy_response()).findMimeField("Host") would not compile in my stuff because moving is deleted for the message classes.

@ywkaras ywkaras force-pushed the cppapi_msg branch 3 times, most recently from 9a45bdb to 46be42a Compare August 14, 2019 22:09
@ywkaras
Copy link
Contributor Author

ywkaras commented Aug 14, 2019

@SolidWallOfCode for the "Transaction Box" stuff, do you have any gold tests that exercise it? If you're saying I should drop what I'm doing and work on Transaction Box instead, the problem is, it's not clear to me what all its goals are. I believe that a C++ utility, and yea even life itself, can still be worthwhile even if it uses neither std::tuple nor std::function.

MimeField
newMimeField()
{
assert(hasMsg());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't use the ink_assert or ink_release_assert ?

Copy link
Contributor Author

@ywkaras ywkaras Aug 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This header is exported to plugin code, so it has to be TSAssert(). See line 31, I removed the use of C assert. I verified that __OPTIMIZE__ is defined by both clang and gcc. The problem with using TSAssert (or ink_assert) directly is that (as in the check above) you also don't want any functions in the boolean expression called in the non-debug build. (Although, it this particular case, it wouldn't matter as hasMsg() would be inlined and elided by the optimizer.)

bool
init(void *txnHndl)
{
assert(!hasMsg());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems obey the ATS Coding Style. See here https://cwiki.apache.org/confluence/display/TS/Coding+Style

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify? I don't find any mention of assert in the Coding Style.

@SolidWallOfCode
Copy link
Member

TxnBox doesn't have any gold tests, but the equivalent classes are used extensively in the code so there is a lot of example use. I'm currently working on writing replay files for testing purposes.

The goals of TxnBox as a plugin aren't really relevant to this discussion. What is important from there is that it needs to interact with the C plugin API and wants to have C++ wrappers to do that, for which reason I have added code very similar to this. The point to address is, what are the goals of those C++ wrappers for the C plugin API? My version has been driven by the use cases that have arisen in TxnBox. For instance, there is a directive to set a field on the proxy request. How would that look with your utilities?


MimeField(MimeField &&source);

// Move assign only allowed if the two instances refer to the same message.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this restriction?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because you can't change a reference.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, you can, I do it, but it is a bit of a cheat.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do you do it?

@ywkaras
Copy link
Contributor Author

ywkaras commented Aug 15, 2019

@SolidWallOfCode It seems to me like what I'm doing is a thinner layer over the TS API HTTP message access functions. It's not immediately apparent to me what your goals are with the added complexity.

@ywkaras
Copy link
Contributor Author

ywkaras commented Aug 15, 2019

Setting a field to a single new value, in the general case, would look like:

MimeField f(msg, name);
if (f.valid()) {
  // Clear current values.
  MimeField fd = f.nextDup();
  while (fd.valid()) {
    f.destroy();
    f  = std::move(fd);
    fd = f.nextDup();
  }
  // Set single new value.
  f.clearValues();
  f.valAppend("New-Value");
}

@ywkaras ywkaras force-pushed the cppapi_msg branch 4 times, most recently from 4bc5467 to 6d93bc5 Compare August 20, 2019 00:15
@SolidWallOfCode
Copy link
Member

I'm not sure what you mean by "added complexity". I think copying the TS C API values is a simpler implementation that using references across objects, so in my view your implementation has added complexity both internally and externally. My goal is to make the use of the classes as simple and robust as possible. Users shouldn't have to carefully design their use to accommodate internal implementation restrictions - the implementation should accommodate any reasonable use.

@ywkaras
Copy link
Contributor Author

ywkaras commented Aug 23, 2019

This is blocked by https://www.mail-archive.com/dev@trafficserver.apache.org/msg15104.html . Implementing this would allow the message objects to be copyable, which @SolidWallOfCode thinks is important.

@ywkaras ywkaras force-pushed the cppapi_msg branch 2 times, most recently from 7be5328 to e98399f Compare September 16, 2019 17:08
@ywkaras ywkaras changed the title Add classes for convenient manipulation of components of HTTP messages. Add classes for convenient manipulation in plugins of components of HTTP messages. Sep 20, 2019
@ywkaras ywkaras marked this pull request as ready for review September 20, 2019 23:16
@zwoop zwoop added this to the 10.0.0 milestone Nov 4, 2019
@zwoop zwoop added the Core label Nov 4, 2019
@ywkaras
Copy link
Contributor Author

ywkaras commented Jun 16, 2020

Note: this is TS CPPAPI, not Core.

@ywkaras
Copy link
Contributor Author

ywkaras commented Jun 26, 2020

[approve ci autest]

# limitations under the License.

Test.Summary = '''
Test tscpp/api/MsgComp.h:w
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No :w.

'proxy.config.diags.debug.tags': 'test_msg_comp',
})

Test.PreparePlugin(Test.Variables.AtsTestToolsDir + '/plugins/test_msg_comp.cc', ts)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have to change this to build in core since that's the New World Order.


#include <tscpp/api/HttpMsgComp.h>

// TSReleaseAssert() doesn't seem to produce any logging output for a debug build, so do both kinds of assert.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to work now so change to simply use TSReleaseAssert().

@ywkaras ywkaras marked this pull request as draft June 26, 2020 16:22
@ywkaras ywkaras added CPP API and removed Core labels Jun 26, 2020
@ywkaras ywkaras modified the milestones: 10.0.0, Sometime Aug 31, 2020
@ywkaras ywkaras force-pushed the cppapi_msg branch 3 times, most recently from a89efec to 626c6fb Compare January 9, 2021 02:49
@ywkaras ywkaras marked this pull request as ready for review January 9, 2021 03:20
…TTP messagess.

These classes may be used independently of other parts of the TS CPP API.
@ywkaras ywkaras marked this pull request as draft January 21, 2021 22:29
@ywkaras
Copy link
Contributor Author

ywkaras commented Jan 21, 2021

This PR is working properly, but marked as draft because we're not sure we want it.

@ywkaras ywkaras closed this May 24, 2021
@zwoop zwoop removed this from the Sometime milestone Sep 23, 2021
@ywkaras ywkaras removed the Dormant label Feb 4, 2022
ywkaras pushed a commit to ywkaras/trafficserver that referenced this pull request Feb 4, 2022
…response body.

Also add classes to CPP API for convenient manipulation of components of HTTP messagess.
These classes may be used independently of other parts of the TS CPP API.  (This PR is
absorbing PR apache#5812.)

Adds Au test with plugin forcing various errors on various hooks, with default body
or set body.
ywkaras pushed a commit to ywkaras/trafficserver that referenced this pull request Feb 4, 2022
…response body.

Also add classes to CPP API for convenient manipulation of components of HTTP messagess.
These classes may be used independently of other parts of the TS CPP API.  (This PR is
absorbing PR apache#5812.)

Adds Au test with plugin forcing various errors on various hooks, with default body
or set body.
ywkaras pushed a commit to ywkaras/trafficserver that referenced this pull request Feb 4, 2022
…response body.

Also add classes to CPP API for convenient manipulation of components of HTTP messagess.
These classes may be used independently of other parts of the TS CPP API.  (This PR is
absorbing PR apache#5812.)

Adds Au test with plugin forcing various errors on various hooks, with default body
or set body.
@ywkaras
Copy link
Contributor Author

ywkaras commented Feb 10, 2022

@zwoop zwoop added Stale and removed Dormant labels Feb 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants