Open rnapier opened 10 years ago
I agree with the principle of keeping things together, but it makes the codebase much harder to navigate (and makes the naming quite messy). Bear in mind that you can still disable SPDY/2 support with spdy.DisableSpdyVersion(2)
.
Another option would be some kind of registration interface where you add support for different protocol versions by importing those packages, but then most users would need to import three packages (spdy
, spdy/spdy2
, and spdy/spdy3
), which is far from ideal.
The main issue is the circular import you mention. If it weren't for that, I would've left what's currently in spdy/common/{interfaces.go, types.go, errors.go}
in spdy
. I'm not wildly happy with it either, and am working on some kind of solution.
However, most users shouldn't need to import spdy/common
, since the core public API is in spdy
still. Since common.Receiver
is an interface, you should be able to define your own (or use nil
) without importing the package.
I'll continue to work on a better structure, but I'm really not keen to move all of spdy2
and spdy3
back into spdy
, since it'll result in an unpleasant amount of clutter.
I went down this same road because I also am working on a large project. The answer after much gnashing of teeth was to put all the files that have to build together into a single directory. That's what the golang-nuts recommend as well. Only make directories for pieces you can build separately. The clutter is worth it to avoid the headaches and fragility (small changes reintroduce circular dependencies, which then requires API changes to fix). I went round and round; in the end, one directory has been much better.
Regarding impact on callers, I need access to the spdy.Conn for dealing with the proxy code. That's where I wound up with common.Conn (which is confusing very confusing). You have the same problem in examples/proxy_server/proxy_server.go.
Yeah, I see what you mean. I'm currently in the process of decoupling
spdy2
and spdy3
from common
in the hope that they can be used
independently. That way, you can use spdy
if you don't care much about
the internals, or you can use a specific package on its own. In your case,
you should be able to use just spdy3
.
One part of this is to separate out functionality. Rather than Conn
being
a massive interface, it should just have the bare essentials, with extra
interfaces for other stuff. This should make it easier to decouple the
different packages.
On 10 June 2014 19:25, Rob Napier notifications@github.com wrote:
I went down this same road because I also am working on a large project. The answer after much gnashing of teeth was to put all the files that have to build together into a single directory. That's what the golang-nuts recommend as well. Only make directories for pieces you can build separately. The clutter is worth it to avoid the headaches and fragility (small changes reintroduce circular dependencies, which then requires API changes to fix). I went round and round; in the end, one directory has been much better.
Regarding impact on callers, I need access to the spdy.Conn for dealing with the proxy code. That's where I wound up with common.Conn (which is confusing very confusing). You have the same problem in examples/proxy_server/proxy_server.go.
— Reply to this email directly or view it on GitHub https://github.com/SlyMarbo/spdy/issues/61#issuecomment-45652192.
The new
common
package leads to the typecommon.Conn
,common.Receiver
, etc. exposed to the caller. That's a very awkward name. The caller expects these to be in thespdy
package. I believe everything in thecommon
package should be moved to the top-levelspdy
.(I'm aware of the circular dependency. I'm working through some solutions to that.)
As I dig into this more, I realize the problem. Go packages don't exist for source code organization. They only exist for managing independent modules. There shouldn't be a
spdy2
directory unless it is possible to buildspdy
without it. I actually would prefer that (I don't want to support spdy2 and don't want the code), but it's not how the code is currently structured.The simplest solution is to move the subdirectories back into the root directory to match how the code currently works. I believe that should happen now; the current structure is just too confusing on callers IMO.
My recommendation for making it work better is this:
There should be a spdy.Protocol interface implemented by spdy2.Prococol and spdy3.Protocol. spdy.New*Conn() should take a slice of Protocols.
In each place that the protocol is checked (in RoundTrip() for instance), each Protocol should be asked if it can handle it, and if it can, it should be handed off.
A default list of all protocols could be returned from spdyutil so that callers don't have to construct their own list, but callers like me could construct their own list if they want to limit the protocols they support.
I can put together a PR for this recommendation over the next week or so.