Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vast Tracker Injection Design Review [DRAFT] #3039

Conversation

Pubmatic-Dhruv-Sonone
Copy link
Contributor

@Pubmatic-Dhruv-Sonone Pubmatic-Dhruv-Sonone commented Aug 21, 2023

This PR consist of different approaches for vast event tracker injection.

Issue: #1725

BenchMark:

// BenchmarkXMLParser-12    	        10081	         114797 ns/op        38260 B/op	     333 allocs/op
// BenchmarkXMLEncoding-12              10802	         109733 ns/op        38601 B/op	     286 allocs/op
// BenchmarkStructUnmarshal-12          4402	         239360 ns/op        72024 B/op	     829 allocs/op
// BenchmarkStringParser-12    	        34964	         31871  ns/op        28325 B/op	     30 allocs/op
// BenchmarkETree-12    	        5698	         180206 ns/op        61769 B/op	     792 allocs/op

@Pubmatic-Dhruv-Sonone Pubmatic-Dhruv-Sonone changed the title Vast Tracker Injection Design Review Vast Tracker Injection Design Review [DRAFT] Aug 21, 2023
}
}

func (builder *TrackerInjector) Build(vastXML string, NURL string) string {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can repeated strings like "TrackingEvents", "VideoClicks", "Tracking", be extracted to constants?

inline.AddChild(impression)
}
for _, url := range builder.events.Errors {
url, _ := builder.replacer.Replace(url, builder.provider)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you shouldn't ignore the error being returned here

builder.provider.PopulateEventMacros("creativeId", "", "")

for _, url := range builder.events.VideoClicks {
url, _ := builder.replacer.Replace(url, builder.provider)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you shouldn't ignore the error being returned here

builder.provider.PopulateEventMacros("creativeID", "", "")

for _, url := range builder.events.NonLinearClickTracking {
url, _ := builder.replacer.Replace(url, builder.provider)
Copy link
Contributor

Choose a reason for hiding this comment

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

Same error related comment

Comment on lines +148 to +154
// goos: darwin
// goarch: amd64
// pkg: github.com/prebid/prebid-server/exchange/injector/etree
// cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
// BenchmarkETree-12 5698 180206 ns/op 61769 B/op 792 allocs/op
// PASS
// ok github.com/prebid/prebid-server/exchange/injector/etree 1.497s
Copy link
Contributor

Choose a reason for hiding this comment

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

Will these comments be removed when this ready to be taken off as draft?

}

func parseVastXML(vastXML []byte) []Ad {

Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: Can you remove blank line here

}

func (builder *TrackerInjector) Build(vastXML string, NURL string) string {

Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: Can you remove blank line here

}

func (builder *TrackerInjector) addEvent(buf *strings.Builder, pair pair) {

Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: Can you remove blank line here

// Nodes []Node `xml:",any"`
}

func main() {
Copy link
Contributor

Choose a reason for hiding this comment

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

This main function needs code coverage

outputXML.WriteString("</TrackingEvents>")
encoder.EncodeToken(tt)
}
case "Linear":
Copy link
Contributor

Choose a reason for hiding this comment

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

This linear case needs code coverage

@SyntaxNode
Copy link
Contributor

@AlexBVolcy I think you may have misunderstood the intent of this PR. It proposes several algorithms for implementing XML injector tracking. @Pubmatic-Dhruv-Sonone is seeking our input on which approach is preferred.

@SyntaxNode
Copy link
Contributor

@Pubmatic-Dhruv-Sonone Thank you for implementing on all of the options and including detailed benchmark results.

While StringParser is the clear winner in terms of speed and allocations, I'm worried how it might behave in the case of invalid xml, which may be intentional as an attack on the system. We've had issues a long time ago with string shortcuts for json generation. What do others think about this?

XMLParser and XMLEncoder are essentially tied for first among the options which validate the xml structure. The Encoder has a slight memory advantage with cleaner code IMHO, making it a winner in my view. Rather than constantly flushing the encoder and outputting xml directly to the output buffer, could use the encoder to construct those tags?

@Pubmatic-Dhruv-Sonone
Copy link
Contributor Author

Pubmatic-Dhruv-Sonone commented Aug 31, 2023

@Pubmatic-Dhruv-Sonone Thank you for implementing on all of the options and including detailed benchmark results.

While StringParser is the clear winner in terms of speed and allocations, I'm worried how it might behave in the case of invalid xml, which may be intentional as an attack on the system. We've had issues a long time ago with string shortcuts for json generation. What do others think about this?

XMLParser and XMLEncoder are essentially tied for first among the options which validate the xml structure. The Encoder has a slight memory advantage with cleaner code IMHO, making it a winner in my view. Rather than constantly flushing the encoder and outputting xml directly to the output buffer, could use the encoder to construct those tags?

@SyntaxNode Updated the XMLEncoder approach to encode tags instead of flushing to output buffer.
Below is the benchmark for the updated approach. The performance has degraded after the changes.

// goos: darwin
// goarch: amd64
// pkg: github.com/prebid/prebid-server/exchange/injector/xml_encoder
// cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
// BenchmarkXMLEncoding-12    	    6666	    158149 ns/op	   53132 B/op	     398 allocs/op
// PASS
// ok  	github.com/prebid/prebid-server/exchange/injector/xml_encoder	1.395s

Also in XMLEncoder approach, sequence of the tags is not maintained as we are injecting child tag just before the end of parent tags.

Ex If vast xml already has a Impression tag then this approach injects new Impression tag before the ending Inline or Wrapper tag. This might break the vast xsd validation as it expected similar tags to be grouped together.

The StringParser approach cannot validate vast xml. Also if some attributes are to be extracted from the tags for tracker macro replacement , we will have to add separate handling for each attribute.

@Pubmatic-Dhruv-Sonone
Copy link
Contributor Author

@SyntaxNode I changed XMLEncoder approach as suggested by you, Do you have anymore thoughts regarding the approaches?

@SyntaxNode
Copy link
Contributor

@Pubmatic-Dhruv-Sonone Since I think we've selected a design, can we close this PR? You can open a new PR with the final code when you're ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants