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

Make dns resolve paths under _dnslink.example.com #2191

Merged
merged 1 commit into from
Jan 29, 2016

Conversation

Kubuxu
Copy link
Member

@Kubuxu Kubuxu commented Jan 12, 2016

Thus allowing to CNAME main site entry to gateway and still specify dnslink.

Resolves ipfs/notes#39. Option 4 and 5.

Would be great if merged with #2139, and shouldn't even conflict (depending on merger)

Also if you have any comments to the code, I would love to hear them. If anything could have been done better... I am not proficient in Go..

@jbenet
Copy link
Member

jbenet commented Jan 13, 2016

Great to see this implemented, thanks!

resChan := make(chan lookupRes)

for _, prefix := range prefixes {
go workDomain(r, prefix + segments[0], resChan)
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 this leaks goroutines? will want to do a waitgroup sync, and buffer the channel with len(prefixes)

Copy link
Member

Choose a reason for hiding this comment

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

also, actually no, i think these should not be concurrent and we unfort need them to be sequential for correctness.? and yes, i think we said the _dnslink. prefix had to be first (is this right @lgierth?)

Copy link
Member Author

Choose a reason for hiding this comment

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

It would be best done concurrently but with _dnslink. starting first. This way on Unix they will be fully concurrent and in case of everything else sequential.

If someone throws different hashes into both places, sorry, but in my opinion it is his problem. Doing it sequentially creates performance trade-off for someone saying conflicting things (which will be really rare).

Copy link

Choose a reason for hiding this comment

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

also, actually no, i think these should not be concurrent and we unfort need them to be sequential for correctness.? and yes, i think we said the _dnslink. prefix had to be first (is this right @lgierth?)

@jbenet yes the _dnslink. record should take precedence, but we can still resolve both concurrently, and as soon as the prefixed record is resolved, we can make a decision.

That way the runtime is roughly max(A, B) and not sum(A, B).

@Kubuxu
Copy link
Member Author

Kubuxu commented Jan 13, 2016

Made it so goroutines start in order. It is still concurrent in case of Unix and in case of other systems will behave as sequential (they use native lib for resolving).

In my opinion if someone places different dnslinks under _dnslink. and . the result should be just undefined.

@Kubuxu
Copy link
Member Author

Kubuxu commented Jan 14, 2016

So the final logic

  1. Start both
  2. Wait .dnslink resolution.
  3. If unsuccessful return result of . resolution.

@ghost
Copy link

ghost commented Jan 14, 2016

I think the goroutines don't neccessarily need to start in order. The only thing that needs to happen is that if (= as soon as) _dnslink. resolves successfully, we return early and cancel the other goroutine. We don't need its result if we already know that we'll pick the other result.

  • start lookup with _dnslink. prefix
  • start lookup without prefix
  • when lookup with prefix finishes
    • if success
      • return with that result
      • cancel without-prefix lookup
    • if failure
      • do nothing
  • when without-prefix lookup finishes
    • if success and prefix lookup failed
      • return without-prefix result
    • if failure
      • do nothing
    • for additional safety:
      • if prefix lookup succeeded
        • do nothing, we are being cancelled right now anyway

edit: removed a stray line at the end, s/promises/goroutines/

@ghost
Copy link

ghost commented Jan 14, 2016

Eventually we might want to put circuit breakers around all DNS lookups, in order to isolate potential DNS breakages that we can do nothing about. But that's a whole different story for another time.

@Kubuxu Kubuxu force-pushed the feature/dnslink branch 3 times, most recently from c3d9180 to 62d06e7 Compare January 15, 2016 08:50
@Kubuxu
Copy link
Member Author

Kubuxu commented Jan 15, 2016

I've made it so it start concurrently, waits for _dnslink. and if it fails uses .. So almost exactly as lgierth said apart from cancelling but there is no much need for it with only two requests which probably start concurrently.

@jbenet
Copy link
Member

jbenet commented Jan 24, 2016

SGTM!

@lgierth do "unsuccessful" dns requests get cached? or will this always cause a request hit initially?

@@ -129,4 +155,6 @@ func TestDNSResolution(t *testing.T) {
testResolution(t, r, "withrecsegment.example.com/test2", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test2", nil)
testResolution(t, r, "withrecsegment.example.com/test3/", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test3/", nil)
testResolution(t, r, "withtrailingrec.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/", nil)
testResolution(t, r, "double.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
testResolution(t, r, "conflict.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE", nil)
Copy link
Member

Choose a reason for hiding this comment

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

👍 great testing adds

@jbenet
Copy link
Member

jbenet commented Jan 24, 2016

this LGTM and RFM. want to hear from @lgierth first, as if we're introducing lots of waiting and lack of caching would be good to be 100% sure we want this.

@ghost
Copy link

ghost commented Jan 25, 2016

@lgierth do "unsuccessful" dns requests get cached? or will this always cause a request hit initially?

@jbenet not within go-land. This PR doesn't make the situation worse though. You could argue that resolving two records instead of one makes it more likely that one of them is a "long tail" request, but meh.

Let's look into decoupling ourselves from failures outside our reach though! Caches and circuit breakers! :)

👍 RFM

@ghost ghost added the RFM label Jan 25, 2016
@ghost ghost mentioned this pull request Jan 25, 2016
@ghost ghost assigned jbenet Jan 25, 2016
@RichardLitt
Copy link
Member

Can we merge this? We've got two RFM.

@ghost
Copy link

ghost commented Jan 29, 2016

Yep let's get it in, it'll also make my own life a lot easier regarding management of domains :)

subChan := make(chan lookupRes, 1)
go workDomain(r, "_dnslink." + domain, subChan)

subRes := <- subChan
Copy link
Member

Choose a reason for hiding this comment

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

sorry to hang this PR up any longer, but if you could change your channel receives to also check the context, that would be super fantastic:

var subRes *lookupRes
select {
    case subRes = <-subChan:
    case <-ctx.Done():
        return "", ctx.Err()
}

do that for this one and the rootChan one a little lower and i'll merge asap

Thus allowing to CNAME main site entry to gateway and stil specify
dnslink.

License: MIT
Signed-off-by: Jakub Sztandera <[email protected]>
@Kubuxu
Copy link
Member Author

Kubuxu commented Jan 29, 2016

@whyrusleeping I've addressed the comment.

@whyrusleeping
Copy link
Member

LGTM

whyrusleeping added a commit that referenced this pull request Jan 29, 2016
Make dns resolve paths under _dnslink.example.com
@whyrusleeping whyrusleeping merged commit ba148b2 into ipfs:master Jan 29, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants