Merge pull request #32822 from timothysc/etcd_TestWatch
Automatic merge from submit-queue Update etcd godep to 3.0.9 to address TestWatch issues fixes TestWatch issues #32770 addresses: https://github.com/coreos/etcd/pull/6367
This commit is contained in:
		
							
								
								
									
										244
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										244
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -353,263 +353,263 @@
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/alarm",
 | 
								"ImportPath": "github.com/coreos/etcd/alarm",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/auth",
 | 
								"ImportPath": "github.com/coreos/etcd/auth",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/auth/authpb",
 | 
								"ImportPath": "github.com/coreos/etcd/auth/authpb",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/client",
 | 
								"ImportPath": "github.com/coreos/etcd/client",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/clientv3",
 | 
								"ImportPath": "github.com/coreos/etcd/clientv3",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/compactor",
 | 
								"ImportPath": "github.com/coreos/etcd/compactor",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/discovery",
 | 
								"ImportPath": "github.com/coreos/etcd/discovery",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/error",
 | 
								"ImportPath": "github.com/coreos/etcd/error",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/etcdserver",
 | 
								"ImportPath": "github.com/coreos/etcd/etcdserver",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/etcdserver/api",
 | 
								"ImportPath": "github.com/coreos/etcd/etcdserver/api",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http",
 | 
								"ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http/httptypes",
 | 
								"ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http/httptypes",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc",
 | 
								"ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes",
 | 
								"ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/etcdserver/auth",
 | 
								"ImportPath": "github.com/coreos/etcd/etcdserver/auth",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb",
 | 
								"ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/etcdserver/membership",
 | 
								"ImportPath": "github.com/coreos/etcd/etcdserver/membership",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/etcdserver/stats",
 | 
								"ImportPath": "github.com/coreos/etcd/etcdserver/stats",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/integration",
 | 
								"ImportPath": "github.com/coreos/etcd/integration",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/lease",
 | 
								"ImportPath": "github.com/coreos/etcd/lease",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/lease/leasehttp",
 | 
								"ImportPath": "github.com/coreos/etcd/lease/leasehttp",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/lease/leasepb",
 | 
								"ImportPath": "github.com/coreos/etcd/lease/leasepb",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/mvcc",
 | 
								"ImportPath": "github.com/coreos/etcd/mvcc",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/mvcc/backend",
 | 
								"ImportPath": "github.com/coreos/etcd/mvcc/backend",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/mvcc/mvccpb",
 | 
								"ImportPath": "github.com/coreos/etcd/mvcc/mvccpb",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/adt",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/adt",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/contention",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/contention",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/crc",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/crc",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/fileutil",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/fileutil",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/httputil",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/httputil",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/idutil",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/idutil",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/ioutil",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/ioutil",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/logutil",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/logutil",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/netutil",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/netutil",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/pathutil",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/pathutil",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/pbutil",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/pbutil",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/runtime",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/runtime",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/schedule",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/schedule",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/testutil",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/testutil",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/tlsutil",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/tlsutil",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/transport",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/transport",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/types",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/types",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/pkg/wait",
 | 
								"ImportPath": "github.com/coreos/etcd/pkg/wait",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/raft",
 | 
								"ImportPath": "github.com/coreos/etcd/raft",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/raft/raftpb",
 | 
								"ImportPath": "github.com/coreos/etcd/raft/raftpb",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/rafthttp",
 | 
								"ImportPath": "github.com/coreos/etcd/rafthttp",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/snap",
 | 
								"ImportPath": "github.com/coreos/etcd/snap",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/snap/snappb",
 | 
								"ImportPath": "github.com/coreos/etcd/snap/snappb",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/store",
 | 
								"ImportPath": "github.com/coreos/etcd/store",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/version",
 | 
								"ImportPath": "github.com/coreos/etcd/version",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/wal",
 | 
								"ImportPath": "github.com/coreos/etcd/wal",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/etcd/wal/walpb",
 | 
								"ImportPath": "github.com/coreos/etcd/wal/walpb",
 | 
				
			||||||
			"Comment": "v3.0.6",
 | 
								"Comment": "v3.0.9",
 | 
				
			||||||
			"Rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0"
 | 
								"Rev": "494c0126596c0e7cd59686a2e7afc90fe3296079"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/go-oidc/http",
 | 
								"ImportPath": "github.com/coreos/go-oidc/http",
 | 
				
			||||||
@@ -2418,48 +2418,48 @@
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "google.golang.org/grpc",
 | 
								"ImportPath": "google.golang.org/grpc",
 | 
				
			||||||
			"Comment": "v1.0.0-6-g02fca89",
 | 
								"Comment": "v1.0.0-183-g231b4cf",
 | 
				
			||||||
			"Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03"
 | 
								"Rev": "231b4cfea0e79843053a33f5fe90bd4d84b23cd3"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "google.golang.org/grpc/codes",
 | 
								"ImportPath": "google.golang.org/grpc/codes",
 | 
				
			||||||
			"Comment": "v1.0.0-6-g02fca89",
 | 
								"Comment": "v1.0.0-183-g231b4cf",
 | 
				
			||||||
			"Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03"
 | 
								"Rev": "231b4cfea0e79843053a33f5fe90bd4d84b23cd3"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "google.golang.org/grpc/credentials",
 | 
								"ImportPath": "google.golang.org/grpc/credentials",
 | 
				
			||||||
			"Comment": "v1.0.0-6-g02fca89",
 | 
								"Comment": "v1.0.0-183-g231b4cf",
 | 
				
			||||||
			"Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03"
 | 
								"Rev": "231b4cfea0e79843053a33f5fe90bd4d84b23cd3"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "google.golang.org/grpc/grpclog",
 | 
								"ImportPath": "google.golang.org/grpc/grpclog",
 | 
				
			||||||
			"Comment": "v1.0.0-6-g02fca89",
 | 
								"Comment": "v1.0.0-183-g231b4cf",
 | 
				
			||||||
			"Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03"
 | 
								"Rev": "231b4cfea0e79843053a33f5fe90bd4d84b23cd3"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "google.golang.org/grpc/internal",
 | 
								"ImportPath": "google.golang.org/grpc/internal",
 | 
				
			||||||
			"Comment": "v1.0.0-6-g02fca89",
 | 
								"Comment": "v1.0.0-183-g231b4cf",
 | 
				
			||||||
			"Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03"
 | 
								"Rev": "231b4cfea0e79843053a33f5fe90bd4d84b23cd3"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "google.golang.org/grpc/metadata",
 | 
								"ImportPath": "google.golang.org/grpc/metadata",
 | 
				
			||||||
			"Comment": "v1.0.0-6-g02fca89",
 | 
								"Comment": "v1.0.0-183-g231b4cf",
 | 
				
			||||||
			"Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03"
 | 
								"Rev": "231b4cfea0e79843053a33f5fe90bd4d84b23cd3"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "google.golang.org/grpc/naming",
 | 
								"ImportPath": "google.golang.org/grpc/naming",
 | 
				
			||||||
			"Comment": "v1.0.0-6-g02fca89",
 | 
								"Comment": "v1.0.0-183-g231b4cf",
 | 
				
			||||||
			"Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03"
 | 
								"Rev": "231b4cfea0e79843053a33f5fe90bd4d84b23cd3"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "google.golang.org/grpc/peer",
 | 
								"ImportPath": "google.golang.org/grpc/peer",
 | 
				
			||||||
			"Comment": "v1.0.0-6-g02fca89",
 | 
								"Comment": "v1.0.0-183-g231b4cf",
 | 
				
			||||||
			"Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03"
 | 
								"Rev": "231b4cfea0e79843053a33f5fe90bd4d84b23cd3"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "google.golang.org/grpc/transport",
 | 
								"ImportPath": "google.golang.org/grpc/transport",
 | 
				
			||||||
			"Comment": "v1.0.0-6-g02fca89",
 | 
								"Comment": "v1.0.0-183-g231b4cf",
 | 
				
			||||||
			"Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03"
 | 
								"Rev": "231b4cfea0e79843053a33f5fe90bd4d84b23cd3"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "gopkg.in/gcfg.v1",
 | 
								"ImportPath": "gopkg.in/gcfg.v1",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								vendor/github.com/coreos/etcd/auth/range_perm_cache.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/coreos/etcd/auth/range_perm_cache.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -22,7 +22,10 @@ import (
 | 
				
			|||||||
	"github.com/coreos/etcd/mvcc/backend"
 | 
						"github.com/coreos/etcd/mvcc/backend"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// isSubset returns true if a is a subset of b
 | 
					// isSubset returns true if a is a subset of b.
 | 
				
			||||||
 | 
					// If a is a prefix of b, then a is a subset of b.
 | 
				
			||||||
 | 
					// Given intervals [a1,a2) and [b1,b2), is
 | 
				
			||||||
 | 
					// the a interval a subset of b?
 | 
				
			||||||
func isSubset(a, b *rangePerm) bool {
 | 
					func isSubset(a, b *rangePerm) bool {
 | 
				
			||||||
	switch {
 | 
						switch {
 | 
				
			||||||
	case len(a.end) == 0 && len(b.end) == 0:
 | 
						case len(a.end) == 0 && len(b.end) == 0:
 | 
				
			||||||
@@ -32,9 +35,11 @@ func isSubset(a, b *rangePerm) bool {
 | 
				
			|||||||
		// b is a key, a is a range
 | 
							// b is a key, a is a range
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	case len(a.end) == 0:
 | 
						case len(a.end) == 0:
 | 
				
			||||||
		return 0 <= bytes.Compare(a.begin, b.begin) && bytes.Compare(a.begin, b.end) <= 0
 | 
							// a is a key, b is a range. need b1 <= a1 and a1 < b2
 | 
				
			||||||
 | 
							return bytes.Compare(b.begin, a.begin) <= 0 && bytes.Compare(a.begin, b.end) < 0
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return 0 <= bytes.Compare(a.begin, b.begin) && bytes.Compare(a.end, b.end) <= 0
 | 
							// both are ranges. need b1 <= a1 and a2 <= b2
 | 
				
			||||||
 | 
							return bytes.Compare(b.begin, a.begin) <= 0 && bytes.Compare(a.end, b.end) <= 0
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -88,12 +93,18 @@ func mergeRangePerms(perms []*rangePerm) []*rangePerm {
 | 
				
			|||||||
	i := 0
 | 
						i := 0
 | 
				
			||||||
	for i < len(perms) {
 | 
						for i < len(perms) {
 | 
				
			||||||
		begin, next := i, i
 | 
							begin, next := i, i
 | 
				
			||||||
		for next+1 < len(perms) && bytes.Compare(perms[next].end, perms[next+1].begin) != -1 {
 | 
							for next+1 < len(perms) && bytes.Compare(perms[next].end, perms[next+1].begin) >= 0 {
 | 
				
			||||||
			next++
 | 
								next++
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							// don't merge ["a", "b") with ["b", ""), because perms[next+1].end is empty.
 | 
				
			||||||
 | 
							if next != begin && len(perms[next].end) > 0 {
 | 
				
			||||||
			merged = append(merged, &rangePerm{begin: perms[begin].begin, end: perms[next].end})
 | 
								merged = append(merged, &rangePerm{begin: perms[begin].begin, end: perms[next].end})
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								merged = append(merged, perms[begin])
 | 
				
			||||||
 | 
								if next != begin {
 | 
				
			||||||
 | 
									merged = append(merged, perms[next])
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		i = next + 1
 | 
							i = next + 1
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								vendor/github.com/coreos/etcd/clientv3/balancer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/coreos/etcd/clientv3/balancer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -45,6 +45,8 @@ type simpleBalancer struct {
 | 
				
			|||||||
	// pinAddr is the currently pinned address; set to the empty string on
 | 
						// pinAddr is the currently pinned address; set to the empty string on
 | 
				
			||||||
	// intialization and shutdown.
 | 
						// intialization and shutdown.
 | 
				
			||||||
	pinAddr string
 | 
						pinAddr string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						closed bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newSimpleBalancer(eps []string) *simpleBalancer {
 | 
					func newSimpleBalancer(eps []string) *simpleBalancer {
 | 
				
			||||||
@@ -74,15 +76,25 @@ func (b *simpleBalancer) ConnectNotify() <-chan struct{} {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (b *simpleBalancer) Up(addr grpc.Address) func(error) {
 | 
					func (b *simpleBalancer) Up(addr grpc.Address) func(error) {
 | 
				
			||||||
	b.mu.Lock()
 | 
						b.mu.Lock()
 | 
				
			||||||
 | 
						defer b.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// gRPC might call Up after it called Close. We add this check
 | 
				
			||||||
 | 
						// to "fix" it up at application layer. Or our simplerBalancer
 | 
				
			||||||
 | 
						// might panic since b.upc is closed.
 | 
				
			||||||
 | 
						if b.closed {
 | 
				
			||||||
 | 
							return func(err error) {}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(b.upEps) == 0 {
 | 
						if len(b.upEps) == 0 {
 | 
				
			||||||
		// notify waiting Get()s and pin first connected address
 | 
							// notify waiting Get()s and pin first connected address
 | 
				
			||||||
		close(b.upc)
 | 
							close(b.upc)
 | 
				
			||||||
		b.pinAddr = addr.Addr
 | 
							b.pinAddr = addr.Addr
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	b.upEps[addr.Addr] = struct{}{}
 | 
						b.upEps[addr.Addr] = struct{}{}
 | 
				
			||||||
	b.mu.Unlock()
 | 
					
 | 
				
			||||||
	// notify client that a connection is up
 | 
						// notify client that a connection is up
 | 
				
			||||||
	b.readyOnce.Do(func() { close(b.readyc) })
 | 
						b.readyOnce.Do(func() { close(b.readyc) })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return func(err error) {
 | 
						return func(err error) {
 | 
				
			||||||
		b.mu.Lock()
 | 
							b.mu.Lock()
 | 
				
			||||||
		delete(b.upEps, addr.Addr)
 | 
							delete(b.upEps, addr.Addr)
 | 
				
			||||||
@@ -128,13 +140,19 @@ func (b *simpleBalancer) Notify() <-chan []grpc.Address { return b.notifyCh }
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (b *simpleBalancer) Close() error {
 | 
					func (b *simpleBalancer) Close() error {
 | 
				
			||||||
	b.mu.Lock()
 | 
						b.mu.Lock()
 | 
				
			||||||
 | 
						defer b.mu.Unlock()
 | 
				
			||||||
 | 
						// In case gRPC calls close twice. TODO: remove the checking
 | 
				
			||||||
 | 
						// when we are sure that gRPC wont call close twice.
 | 
				
			||||||
 | 
						if b.closed {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						b.closed = true
 | 
				
			||||||
	close(b.notifyCh)
 | 
						close(b.notifyCh)
 | 
				
			||||||
	// terminate all waiting Get()s
 | 
						// terminate all waiting Get()s
 | 
				
			||||||
	b.pinAddr = ""
 | 
						b.pinAddr = ""
 | 
				
			||||||
	if len(b.upEps) == 0 {
 | 
						if len(b.upEps) == 0 {
 | 
				
			||||||
		close(b.upc)
 | 
							close(b.upc)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	b.mu.Unlock()
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								vendor/github.com/coreos/etcd/clientv3/watch.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/coreos/etcd/clientv3/watch.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -669,6 +669,10 @@ func (w *watchGrpcStream) resumeWatchers(wc pb.Watch_WatchClient) error {
 | 
				
			|||||||
	w.mu.RUnlock()
 | 
						w.mu.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, ws := range streams {
 | 
						for _, ws := range streams {
 | 
				
			||||||
 | 
							// drain recvc so no old WatchResponses (e.g., Created messages)
 | 
				
			||||||
 | 
							// are processed while resuming
 | 
				
			||||||
 | 
							ws.drain()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// pause serveStream
 | 
							// pause serveStream
 | 
				
			||||||
		ws.resumec <- -1
 | 
							ws.resumec <- -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -701,6 +705,17 @@ func (w *watchGrpcStream) resumeWatchers(wc pb.Watch_WatchClient) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// drain removes all buffered WatchResponses from the stream's receive channel.
 | 
				
			||||||
 | 
					func (ws *watcherStream) drain() {
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							select {
 | 
				
			||||||
 | 
							case <-ws.recvc:
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// toPB converts an internal watch request structure to its protobuf messagefunc (wr *watchRequest)
 | 
					// toPB converts an internal watch request structure to its protobuf messagefunc (wr *watchRequest)
 | 
				
			||||||
func (wr *watchRequest) toPB() *pb.WatchRequest {
 | 
					func (wr *watchRequest) toPB() *pb.WatchRequest {
 | 
				
			||||||
	req := &pb.WatchCreateRequest{
 | 
						req := &pb.WatchCreateRequest{
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								vendor/github.com/coreos/etcd/discovery/srv.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/coreos/etcd/discovery/srv.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -53,8 +53,8 @@ func SRVGetCluster(name, dns string, defaultToken string, apurls types.URLs) (st
 | 
				
			|||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for _, srv := range addrs {
 | 
							for _, srv := range addrs {
 | 
				
			||||||
			target := strings.TrimSuffix(srv.Target, ".")
 | 
								port := fmt.Sprintf("%d", srv.Port)
 | 
				
			||||||
			host := net.JoinHostPort(target, fmt.Sprintf("%d", srv.Port))
 | 
								host := net.JoinHostPort(srv.Target, port)
 | 
				
			||||||
			tcpAddr, err := resolveTCPAddr("tcp", host)
 | 
								tcpAddr, err := resolveTCPAddr("tcp", host)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				plog.Warningf("couldn't resolve host %s during SRV discovery", host)
 | 
									plog.Warningf("couldn't resolve host %s during SRV discovery", host)
 | 
				
			||||||
@@ -70,8 +70,11 @@ func SRVGetCluster(name, dns string, defaultToken string, apurls types.URLs) (st
 | 
				
			|||||||
				n = fmt.Sprintf("%d", tempName)
 | 
									n = fmt.Sprintf("%d", tempName)
 | 
				
			||||||
				tempName += 1
 | 
									tempName += 1
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			stringParts = append(stringParts, fmt.Sprintf("%s=%s%s", n, prefix, host))
 | 
								// SRV records have a trailing dot but URL shouldn't.
 | 
				
			||||||
			plog.Noticef("got bootstrap from DNS for %s at %s%s", service, prefix, host)
 | 
								shortHost := strings.TrimSuffix(srv.Target, ".")
 | 
				
			||||||
 | 
								urlHost := net.JoinHostPort(shortHost, port)
 | 
				
			||||||
 | 
								stringParts = append(stringParts, fmt.Sprintf("%s=%s%s", n, prefix, urlHost))
 | 
				
			||||||
 | 
								plog.Noticef("got bootstrap from DNS for %s at %s%s", service, prefix, urlHost)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								vendor/github.com/coreos/etcd/etcdserver/server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/coreos/etcd/etcdserver/server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -412,9 +412,14 @@ func NewServer(cfg *ServerConfig) (srv *EtcdServer, err error) {
 | 
				
			|||||||
	srv.kv = mvcc.New(srv.be, srv.lessor, &srv.consistIndex)
 | 
						srv.kv = mvcc.New(srv.be, srv.lessor, &srv.consistIndex)
 | 
				
			||||||
	if beExist {
 | 
						if beExist {
 | 
				
			||||||
		kvindex := srv.kv.ConsistentIndex()
 | 
							kvindex := srv.kv.ConsistentIndex()
 | 
				
			||||||
 | 
							// TODO: remove kvindex != 0 checking when we do not expect users to upgrade
 | 
				
			||||||
 | 
							// etcd from pre-3.0 release.
 | 
				
			||||||
		if snapshot != nil && kvindex < snapshot.Metadata.Index {
 | 
							if snapshot != nil && kvindex < snapshot.Metadata.Index {
 | 
				
			||||||
 | 
								if kvindex != 0 {
 | 
				
			||||||
				return nil, fmt.Errorf("database file (%v index %d) does not match with snapshot (index %d).", bepath, kvindex, snapshot.Metadata.Index)
 | 
									return nil, fmt.Errorf("database file (%v index %d) does not match with snapshot (index %d).", bepath, kvindex, snapshot.Metadata.Index)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								plog.Warningf("consistent index never saved (snapshot index=%d)", snapshot.Metadata.Index)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	srv.consistIndex.setConsistentIndex(srv.kv.ConsistentIndex())
 | 
						srv.consistIndex.setConsistentIndex(srv.kv.ConsistentIndex())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								vendor/github.com/coreos/etcd/pkg/fileutil/dir_unix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/coreos/etcd/pkg/fileutil/dir_unix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					// Copyright 2016 The etcd Authors
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build !windows
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package fileutil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OpenDir opens a directory for syncing.
 | 
				
			||||||
 | 
					func OpenDir(path string) (*os.File, error) { return os.Open(path) }
 | 
				
			||||||
							
								
								
									
										46
									
								
								vendor/github.com/coreos/etcd/pkg/fileutil/dir_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/coreos/etcd/pkg/fileutil/dir_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					// Copyright 2016 The etcd Authors
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build windows
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package fileutil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OpenDir opens a directory in windows with write access for syncing.
 | 
				
			||||||
 | 
					func OpenDir(path string) (*os.File, error) {
 | 
				
			||||||
 | 
						fd, err := openDir(path)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return os.NewFile(uintptr(fd), path), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func openDir(path string) (fd syscall.Handle, err error) {
 | 
				
			||||||
 | 
						if len(path) == 0 {
 | 
				
			||||||
 | 
							return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pathp, err := syscall.UTF16PtrFromString(path)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return syscall.InvalidHandle, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE)
 | 
				
			||||||
 | 
						sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE)
 | 
				
			||||||
 | 
						createmode := uint32(syscall.OPEN_EXISTING)
 | 
				
			||||||
 | 
						fl := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
 | 
				
			||||||
 | 
						return syscall.CreateFile(pathp, access, sharemode, nil, createmode, fl, 0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -96,3 +96,26 @@ func Exist(name string) bool {
 | 
				
			|||||||
	_, err := os.Stat(name)
 | 
						_, err := os.Stat(name)
 | 
				
			||||||
	return err == nil
 | 
						return err == nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZeroToEnd zeros a file starting from SEEK_CUR to its SEEK_END. May temporarily
 | 
				
			||||||
 | 
					// shorten the length of the file.
 | 
				
			||||||
 | 
					func ZeroToEnd(f *os.File) error {
 | 
				
			||||||
 | 
						// TODO: support FALLOC_FL_ZERO_RANGE
 | 
				
			||||||
 | 
						off, err := f.Seek(0, os.SEEK_CUR)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						lenf, lerr := f.Seek(0, os.SEEK_END)
 | 
				
			||||||
 | 
						if lerr != nil {
 | 
				
			||||||
 | 
							return lerr
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err = f.Truncate(off); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// make sure blocks remain allocated
 | 
				
			||||||
 | 
						if err = Preallocate(f, lenf, true); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err = f.Seek(off, os.SEEK_SET)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										103
									
								
								vendor/github.com/coreos/etcd/pkg/ioutil/pagewriter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								vendor/github.com/coreos/etcd/pkg/ioutil/pagewriter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					// Copyright 2016 The etcd Authors
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package ioutil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var defaultBufferBytes = 128 * 1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PageWriter implements the io.Writer interface so that writes will
 | 
				
			||||||
 | 
					// either be in page chunks or from flushing.
 | 
				
			||||||
 | 
					type PageWriter struct {
 | 
				
			||||||
 | 
						w io.Writer
 | 
				
			||||||
 | 
						// pageOffset tracks the page offset of the base of the buffer
 | 
				
			||||||
 | 
						pageOffset int
 | 
				
			||||||
 | 
						// pageBytes is the number of bytes per page
 | 
				
			||||||
 | 
						pageBytes int
 | 
				
			||||||
 | 
						// bufferedBytes counts the number of bytes pending for write in the buffer
 | 
				
			||||||
 | 
						bufferedBytes int
 | 
				
			||||||
 | 
						// buf holds the write buffer
 | 
				
			||||||
 | 
						buf []byte
 | 
				
			||||||
 | 
						// bufWatermarkBytes is the number of bytes the buffer can hold before it needs
 | 
				
			||||||
 | 
						// to be flushed. It is less than len(buf) so there is space for slack writes
 | 
				
			||||||
 | 
						// to bring the writer to page alignment.
 | 
				
			||||||
 | 
						bufWatermarkBytes int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewPageWriter(w io.Writer, pageBytes int) *PageWriter {
 | 
				
			||||||
 | 
						return &PageWriter{
 | 
				
			||||||
 | 
							w:                 w,
 | 
				
			||||||
 | 
							pageBytes:         pageBytes,
 | 
				
			||||||
 | 
							buf:               make([]byte, defaultBufferBytes+pageBytes),
 | 
				
			||||||
 | 
							bufWatermarkBytes: defaultBufferBytes,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (pw *PageWriter) Write(p []byte) (n int, err error) {
 | 
				
			||||||
 | 
						if len(p)+pw.bufferedBytes <= pw.bufWatermarkBytes {
 | 
				
			||||||
 | 
							// no overflow
 | 
				
			||||||
 | 
							copy(pw.buf[pw.bufferedBytes:], p)
 | 
				
			||||||
 | 
							pw.bufferedBytes += len(p)
 | 
				
			||||||
 | 
							return len(p), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// complete the slack page in the buffer if unaligned
 | 
				
			||||||
 | 
						slack := pw.pageBytes - ((pw.pageOffset + pw.bufferedBytes) % pw.pageBytes)
 | 
				
			||||||
 | 
						if slack != pw.pageBytes {
 | 
				
			||||||
 | 
							partial := slack > len(p)
 | 
				
			||||||
 | 
							if partial {
 | 
				
			||||||
 | 
								// not enough data to complete the slack page
 | 
				
			||||||
 | 
								slack = len(p)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// special case: writing to slack page in buffer
 | 
				
			||||||
 | 
							copy(pw.buf[pw.bufferedBytes:], p[:slack])
 | 
				
			||||||
 | 
							pw.bufferedBytes += slack
 | 
				
			||||||
 | 
							n = slack
 | 
				
			||||||
 | 
							p = p[slack:]
 | 
				
			||||||
 | 
							if partial {
 | 
				
			||||||
 | 
								// avoid forcing an unaligned flush
 | 
				
			||||||
 | 
								return n, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// buffer contents are now page-aligned; clear out
 | 
				
			||||||
 | 
						if err = pw.Flush(); err != nil {
 | 
				
			||||||
 | 
							return n, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// directly write all complete pages without copying
 | 
				
			||||||
 | 
						if len(p) > pw.pageBytes {
 | 
				
			||||||
 | 
							pages := len(p) / pw.pageBytes
 | 
				
			||||||
 | 
							c, werr := pw.w.Write(p[:pages*pw.pageBytes])
 | 
				
			||||||
 | 
							n += c
 | 
				
			||||||
 | 
							if werr != nil {
 | 
				
			||||||
 | 
								return n, werr
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							p = p[pages*pw.pageBytes:]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// write remaining tail to buffer
 | 
				
			||||||
 | 
						c, werr := pw.Write(p)
 | 
				
			||||||
 | 
						n += c
 | 
				
			||||||
 | 
						return n, werr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (pw *PageWriter) Flush() error {
 | 
				
			||||||
 | 
						if pw.bufferedBytes == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err := pw.w.Write(pw.buf[:pw.bufferedBytes])
 | 
				
			||||||
 | 
						pw.pageOffset = (pw.pageOffset + pw.bufferedBytes) % pw.pageBytes
 | 
				
			||||||
 | 
						pw.bufferedBytes = 0
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2
									
								
								vendor/github.com/coreos/etcd/version/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/coreos/etcd/version/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -29,7 +29,7 @@ import (
 | 
				
			|||||||
var (
 | 
					var (
 | 
				
			||||||
	// MinClusterVersion is the min cluster version this etcd binary is compatible with.
 | 
						// MinClusterVersion is the min cluster version this etcd binary is compatible with.
 | 
				
			||||||
	MinClusterVersion = "2.3.0"
 | 
						MinClusterVersion = "2.3.0"
 | 
				
			||||||
	Version           = "3.0.6"
 | 
						Version           = "3.0.9"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Git SHA Value will be set during build
 | 
						// Git SHA Value will be set during build
 | 
				
			||||||
	GitSHA = "Not provided (use ./build instead of go build)"
 | 
						GitSHA = "Not provided (use ./build instead of go build)"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								vendor/github.com/coreos/etcd/wal/encoder.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/coreos/etcd/wal/encoder.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,19 +15,24 @@
 | 
				
			|||||||
package wal
 | 
					package wal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"encoding/binary"
 | 
						"encoding/binary"
 | 
				
			||||||
	"hash"
 | 
						"hash"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/coreos/etcd/pkg/crc"
 | 
						"github.com/coreos/etcd/pkg/crc"
 | 
				
			||||||
 | 
						"github.com/coreos/etcd/pkg/ioutil"
 | 
				
			||||||
	"github.com/coreos/etcd/wal/walpb"
 | 
						"github.com/coreos/etcd/wal/walpb"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// walPageBytes is the alignment for flushing records to the backing Writer.
 | 
				
			||||||
 | 
					// It should be a multiple of the minimum sector size so that WAL repair can
 | 
				
			||||||
 | 
					// safely between torn writes and ordinary data corruption.
 | 
				
			||||||
 | 
					const walPageBytes = 8 * minSectorSize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type encoder struct {
 | 
					type encoder struct {
 | 
				
			||||||
	mu sync.Mutex
 | 
						mu sync.Mutex
 | 
				
			||||||
	bw *bufio.Writer
 | 
						bw *ioutil.PageWriter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	crc       hash.Hash32
 | 
						crc       hash.Hash32
 | 
				
			||||||
	buf       []byte
 | 
						buf       []byte
 | 
				
			||||||
@@ -36,7 +41,7 @@ type encoder struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func newEncoder(w io.Writer, prevCrc uint32) *encoder {
 | 
					func newEncoder(w io.Writer, prevCrc uint32) *encoder {
 | 
				
			||||||
	return &encoder{
 | 
						return &encoder{
 | 
				
			||||||
		bw:  bufio.NewWriter(w),
 | 
							bw:  ioutil.NewPageWriter(w, walPageBytes),
 | 
				
			||||||
		crc: crc.New(prevCrc, crcTable),
 | 
							crc: crc.New(prevCrc, crcTable),
 | 
				
			||||||
		// 1MB buffer
 | 
							// 1MB buffer
 | 
				
			||||||
		buf:       make([]byte, 1024*1024),
 | 
							buf:       make([]byte, 1024*1024),
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										67
									
								
								vendor/github.com/coreos/etcd/wal/wal.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										67
									
								
								vendor/github.com/coreos/etcd/wal/wal.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -68,6 +68,10 @@ var (
 | 
				
			|||||||
// The WAL will be ready for appending after reading out all the previous records.
 | 
					// The WAL will be ready for appending after reading out all the previous records.
 | 
				
			||||||
type WAL struct {
 | 
					type WAL struct {
 | 
				
			||||||
	dir string // the living directory of the underlay files
 | 
						dir string // the living directory of the underlay files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// dirFile is a fd for the wal directory for syncing on Rename
 | 
				
			||||||
 | 
						dirFile *os.File
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	metadata []byte           // metadata recorded at the head of each WAL
 | 
						metadata []byte           // metadata recorded at the head of each WAL
 | 
				
			||||||
	state    raftpb.HardState // hardstate recorded at the head of WAL
 | 
						state    raftpb.HardState // hardstate recorded at the head of WAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -106,10 +110,10 @@ func Create(dirpath string, metadata []byte) (*WAL, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, err := f.Seek(0, os.SEEK_END); err != nil {
 | 
						if _, err = f.Seek(0, os.SEEK_END); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := fileutil.Preallocate(f.File, segmentSizeBytes, true); err != nil {
 | 
						if err = fileutil.Preallocate(f.File, segmentSizeBytes, true); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -119,32 +123,33 @@ func Create(dirpath string, metadata []byte) (*WAL, error) {
 | 
				
			|||||||
		encoder:  newEncoder(f, 0),
 | 
							encoder:  newEncoder(f, 0),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	w.locks = append(w.locks, f)
 | 
						w.locks = append(w.locks, f)
 | 
				
			||||||
	if err := w.saveCrc(0); err != nil {
 | 
						if err = w.saveCrc(0); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := w.encoder.encode(&walpb.Record{Type: metadataType, Data: metadata}); err != nil {
 | 
						if err = w.encoder.encode(&walpb.Record{Type: metadataType, Data: metadata}); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := w.SaveSnapshot(walpb.Snapshot{}); err != nil {
 | 
						if err = w.SaveSnapshot(walpb.Snapshot{}); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// rename of directory with locked files doesn't work on windows; close
 | 
						if w, err = w.renameWal(tmpdirpath); err != nil {
 | 
				
			||||||
	// the WAL to release the locks so the directory can be renamed
 | 
					 | 
				
			||||||
	w.Close()
 | 
					 | 
				
			||||||
	if err := os.Rename(tmpdirpath, dirpath); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// reopen and relock
 | 
					
 | 
				
			||||||
	newWAL, oerr := Open(dirpath, walpb.Snapshot{})
 | 
						// directory was renamed; sync parent dir to persist rename
 | 
				
			||||||
	if oerr != nil {
 | 
						pdir, perr := fileutil.OpenDir(path.Dir(w.dir))
 | 
				
			||||||
		return nil, oerr
 | 
						if perr != nil {
 | 
				
			||||||
 | 
							return nil, perr
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, _, _, err := newWAL.ReadAll(); err != nil {
 | 
						if perr = fileutil.Fsync(pdir); perr != nil {
 | 
				
			||||||
		newWAL.Close()
 | 
							return nil, perr
 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return newWAL, nil
 | 
						if perr = pdir.Close(); err != nil {
 | 
				
			||||||
 | 
							return nil, perr
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return w, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Open opens the WAL at the given snap.
 | 
					// Open opens the WAL at the given snap.
 | 
				
			||||||
@@ -154,7 +159,14 @@ func Create(dirpath string, metadata []byte) (*WAL, error) {
 | 
				
			|||||||
// the given snap. The WAL cannot be appended to before reading out all of its
 | 
					// the given snap. The WAL cannot be appended to before reading out all of its
 | 
				
			||||||
// previous records.
 | 
					// previous records.
 | 
				
			||||||
func Open(dirpath string, snap walpb.Snapshot) (*WAL, error) {
 | 
					func Open(dirpath string, snap walpb.Snapshot) (*WAL, error) {
 | 
				
			||||||
	return openAtIndex(dirpath, snap, true)
 | 
						w, err := openAtIndex(dirpath, snap, true)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if w.dirFile, err = fileutil.OpenDir(w.dir); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return w, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// OpenForRead only opens the wal files for read.
 | 
					// OpenForRead only opens the wal files for read.
 | 
				
			||||||
@@ -299,6 +311,18 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb.
 | 
				
			|||||||
			state.Reset()
 | 
								state.Reset()
 | 
				
			||||||
			return nil, state, nil, err
 | 
								return nil, state, nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							// decodeRecord() will return io.EOF if it detects a zero record,
 | 
				
			||||||
 | 
							// but this zero record may be followed by non-zero records from
 | 
				
			||||||
 | 
							// a torn write. Overwriting some of these non-zero records, but
 | 
				
			||||||
 | 
							// not all, will cause CRC errors on WAL open. Since the records
 | 
				
			||||||
 | 
							// were never fully synced to disk in the first place, it's safe
 | 
				
			||||||
 | 
							// to zero them out to avoid any CRC errors from new writes.
 | 
				
			||||||
 | 
							if _, err = w.tail().Seek(w.decoder.lastOffset(), os.SEEK_SET); err != nil {
 | 
				
			||||||
 | 
								return nil, state, nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err = fileutil.ZeroToEnd(w.tail().File); err != nil {
 | 
				
			||||||
 | 
								return nil, state, nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = nil
 | 
						err = nil
 | 
				
			||||||
@@ -317,7 +341,6 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if w.tail() != nil {
 | 
						if w.tail() != nil {
 | 
				
			||||||
		// create encoder (chain crc with the decoder), enable appending
 | 
							// create encoder (chain crc with the decoder), enable appending
 | 
				
			||||||
		_, err = w.tail().Seek(w.decoder.lastOffset(), os.SEEK_SET)
 | 
					 | 
				
			||||||
		w.encoder = newEncoder(w.tail(), w.decoder.lastCRC())
 | 
							w.encoder = newEncoder(w.tail(), w.decoder.lastCRC())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	w.decoder = nil
 | 
						w.decoder = nil
 | 
				
			||||||
@@ -375,6 +398,10 @@ func (w *WAL) cut() error {
 | 
				
			|||||||
	if err = os.Rename(newTail.Name(), fpath); err != nil {
 | 
						if err = os.Rename(newTail.Name(), fpath); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if err = fileutil.Fsync(w.dirFile); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newTail.Close()
 | 
						newTail.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if newTail, err = fileutil.LockFile(fpath, os.O_WRONLY, fileutil.PrivateFileMode); err != nil {
 | 
						if newTail, err = fileutil.LockFile(fpath, os.O_WRONLY, fileutil.PrivateFileMode); err != nil {
 | 
				
			||||||
@@ -477,7 +504,7 @@ func (w *WAL) Close() error {
 | 
				
			|||||||
			plog.Errorf("failed to unlock during closing wal: %s", err)
 | 
								plog.Errorf("failed to unlock during closing wal: %s", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return w.dirFile.Close()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (w *WAL) saveEntry(e *raftpb.Entry) error {
 | 
					func (w *WAL) saveEntry(e *raftpb.Entry) error {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								vendor/github.com/coreos/etcd/wal/wal_unix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/coreos/etcd/wal/wal_unix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					// Copyright 2016 The etcd Authors
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build !windows
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package wal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/coreos/etcd/pkg/fileutil"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (w *WAL) renameWal(tmpdirpath string) (*WAL, error) {
 | 
				
			||||||
 | 
						// On non-Windows platforms, hold the lock while renaming. Releasing
 | 
				
			||||||
 | 
						// the lock and trying to reacquire it quickly can be flaky because
 | 
				
			||||||
 | 
						// it's possible the process will fork to spawn a process while this is
 | 
				
			||||||
 | 
						// happening. The fds are set up as close-on-exec by the Go runtime,
 | 
				
			||||||
 | 
						// but there is a window between the fork and the exec where another
 | 
				
			||||||
 | 
						// process holds the lock.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := os.RemoveAll(w.dir); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := os.Rename(tmpdirpath, w.dir); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						w.fp = newFilePipeline(w.dir, segmentSizeBytes)
 | 
				
			||||||
 | 
						df, err := fileutil.OpenDir(w.dir)
 | 
				
			||||||
 | 
						w.dirFile = df
 | 
				
			||||||
 | 
						return w, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								vendor/github.com/coreos/etcd/wal/wal_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/github.com/coreos/etcd/wal/wal_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					// Copyright 2016 The etcd Authors
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package wal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/coreos/etcd/wal/walpb"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (w *WAL) renameWal(tmpdirpath string) (*WAL, error) {
 | 
				
			||||||
 | 
						// rename of directory with locked files doesn't work on
 | 
				
			||||||
 | 
						// windows; close the WAL to release the locks so the directory
 | 
				
			||||||
 | 
						// can be renamed
 | 
				
			||||||
 | 
						w.Close()
 | 
				
			||||||
 | 
						if err := os.Rename(tmpdirpath, w.dir); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// reopen and relock
 | 
				
			||||||
 | 
						newWAL, oerr := Open(w.dir, walpb.Snapshot{})
 | 
				
			||||||
 | 
						if oerr != nil {
 | 
				
			||||||
 | 
							return nil, oerr
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if _, _, _, err := newWAL.ReadAll(); err != nil {
 | 
				
			||||||
 | 
							newWAL.Close()
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return newWAL, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								vendor/google.golang.org/grpc/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/google.golang.org/grpc/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,17 +1,21 @@
 | 
				
			|||||||
language: go
 | 
					language: go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
go:
 | 
					go:
 | 
				
			||||||
  - 1.5.3
 | 
					  - 1.5.4
 | 
				
			||||||
  - 1.6
 | 
					  - 1.6.3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go_import_path: google.golang.org/grpc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
before_install:
 | 
					before_install:
 | 
				
			||||||
 | 
					  - go get golang.org/x/tools/cmd/goimports
 | 
				
			||||||
 | 
					  - go get github.com/golang/lint/golint
 | 
				
			||||||
  - go get github.com/axw/gocov/gocov
 | 
					  - go get github.com/axw/gocov/gocov
 | 
				
			||||||
  - go get github.com/mattn/goveralls
 | 
					  - go get github.com/mattn/goveralls
 | 
				
			||||||
  - go get golang.org/x/tools/cmd/cover
 | 
					  - go get golang.org/x/tools/cmd/cover
 | 
				
			||||||
 | 
					
 | 
				
			||||||
install:
 | 
					 | 
				
			||||||
  - mkdir -p "$GOPATH/src/google.golang.org"
 | 
					 | 
				
			||||||
  - mv "$TRAVIS_BUILD_DIR" "$GOPATH/src/google.golang.org/grpc"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
script:
 | 
					script:
 | 
				
			||||||
 | 
					  - '! gofmt -s -d -l . 2>&1 | read'
 | 
				
			||||||
 | 
					  - '! goimports -l . | read'
 | 
				
			||||||
 | 
					  - '! golint ./... | grep -vE "(_string|\.pb)\.go:"'
 | 
				
			||||||
 | 
					  - '! go tool vet -all . 2>&1 | grep -vE "constant [0-9]+ not a string in call to Errorf"'
 | 
				
			||||||
  - make test testrace
 | 
					  - make test testrace
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								vendor/google.golang.org/grpc/call.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/google.golang.org/grpc/call.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -36,6 +36,7 @@ package grpc
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
 | 
						"math"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"golang.org/x/net/context"
 | 
						"golang.org/x/net/context"
 | 
				
			||||||
@@ -51,13 +52,20 @@ import (
 | 
				
			|||||||
func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) error {
 | 
					func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) error {
 | 
				
			||||||
	// Try to acquire header metadata from the server if there is any.
 | 
						// Try to acquire header metadata from the server if there is any.
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if _, ok := err.(transport.ConnectionError); !ok {
 | 
				
			||||||
 | 
									t.CloseStream(stream, err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
	c.headerMD, err = stream.Header()
 | 
						c.headerMD, err = stream.Header()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	p := &parser{r: stream}
 | 
						p := &parser{r: stream}
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		if err = recv(p, dopts.codec, stream, dopts.dc, reply); err != nil {
 | 
							if err = recv(p, dopts.codec, stream, dopts.dc, reply, math.MaxInt32); err != nil {
 | 
				
			||||||
			if err == io.EOF {
 | 
								if err == io.EOF {
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -76,6 +84,7 @@ func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHd
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								// If err is connection error, t will be closed, no need to close stream here.
 | 
				
			||||||
			if _, ok := err.(transport.ConnectionError); !ok {
 | 
								if _, ok := err.(transport.ConnectionError); !ok {
 | 
				
			||||||
				t.CloseStream(stream, err)
 | 
									t.CloseStream(stream, err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -90,7 +99,10 @@ func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHd
 | 
				
			|||||||
		return nil, transport.StreamErrorf(codes.Internal, "grpc: %v", err)
 | 
							return nil, transport.StreamErrorf(codes.Internal, "grpc: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = t.Write(stream, outBuf, opts)
 | 
						err = t.Write(stream, outBuf, opts)
 | 
				
			||||||
	if err != nil {
 | 
						// t.NewStream(...) could lead to an early rejection of the RPC (e.g., the service/method
 | 
				
			||||||
 | 
						// does not exist.) so that t.Write could get io.EOF from wait(...). Leave the following
 | 
				
			||||||
 | 
						// recvResponse to get the final status.
 | 
				
			||||||
 | 
						if err != nil && err != io.EOF {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Sent successfully.
 | 
						// Sent successfully.
 | 
				
			||||||
@@ -158,9 +170,9 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
 | 
				
			|||||||
			if _, ok := err.(*rpcError); ok {
 | 
								if _, ok := err.(*rpcError); ok {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err == errConnClosing {
 | 
								if err == errConnClosing || err == errConnUnavailable {
 | 
				
			||||||
				if c.failFast {
 | 
									if c.failFast {
 | 
				
			||||||
					return Errorf(codes.Unavailable, "%v", errConnClosing)
 | 
										return Errorf(codes.Unavailable, "%v", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -176,7 +188,10 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
 | 
				
			|||||||
				put()
 | 
									put()
 | 
				
			||||||
				put = nil
 | 
									put = nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if _, ok := err.(transport.ConnectionError); ok {
 | 
								// Retry a non-failfast RPC when
 | 
				
			||||||
 | 
								// i) there is a connection error; or
 | 
				
			||||||
 | 
								// ii) the server started to drain before this RPC was initiated.
 | 
				
			||||||
 | 
								if _, ok := err.(transport.ConnectionError); ok || err == transport.ErrStreamDrain {
 | 
				
			||||||
				if c.failFast {
 | 
									if c.failFast {
 | 
				
			||||||
					return toRPCErr(err)
 | 
										return toRPCErr(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -184,20 +199,18 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			return toRPCErr(err)
 | 
								return toRPCErr(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Receive the response
 | 
					 | 
				
			||||||
		err = recvResponse(cc.dopts, t, &c, stream, reply)
 | 
							err = recvResponse(cc.dopts, t, &c, stream, reply)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			if put != nil {
 | 
								if put != nil {
 | 
				
			||||||
				put()
 | 
									put()
 | 
				
			||||||
				put = nil
 | 
									put = nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if _, ok := err.(transport.ConnectionError); ok {
 | 
								if _, ok := err.(transport.ConnectionError); ok || err == transport.ErrStreamDrain {
 | 
				
			||||||
				if c.failFast {
 | 
									if c.failFast {
 | 
				
			||||||
					return toRPCErr(err)
 | 
										return toRPCErr(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			t.CloseStream(stream, err)
 | 
					 | 
				
			||||||
			return toRPCErr(err)
 | 
								return toRPCErr(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if c.traceInfo.tr != nil {
 | 
							if c.traceInfo.tr != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										267
									
								
								vendor/google.golang.org/grpc/clientconn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										267
									
								
								vendor/google.golang.org/grpc/clientconn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -43,7 +43,6 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"golang.org/x/net/context"
 | 
						"golang.org/x/net/context"
 | 
				
			||||||
	"golang.org/x/net/trace"
 | 
						"golang.org/x/net/trace"
 | 
				
			||||||
	"google.golang.org/grpc/codes"
 | 
					 | 
				
			||||||
	"google.golang.org/grpc/credentials"
 | 
						"google.golang.org/grpc/credentials"
 | 
				
			||||||
	"google.golang.org/grpc/grpclog"
 | 
						"google.golang.org/grpc/grpclog"
 | 
				
			||||||
	"google.golang.org/grpc/transport"
 | 
						"google.golang.org/grpc/transport"
 | 
				
			||||||
@@ -68,12 +67,14 @@ var (
 | 
				
			|||||||
	// errCredentialsConflict indicates that grpc.WithTransportCredentials()
 | 
						// errCredentialsConflict indicates that grpc.WithTransportCredentials()
 | 
				
			||||||
	// and grpc.WithInsecure() are both called for a connection.
 | 
						// and grpc.WithInsecure() are both called for a connection.
 | 
				
			||||||
	errCredentialsConflict = errors.New("grpc: transport credentials are set for an insecure connection (grpc.WithTransportCredentials() and grpc.WithInsecure() are both called)")
 | 
						errCredentialsConflict = errors.New("grpc: transport credentials are set for an insecure connection (grpc.WithTransportCredentials() and grpc.WithInsecure() are both called)")
 | 
				
			||||||
	// errNetworkIP indicates that the connection is down due to some network I/O error.
 | 
						// errNetworkIO indicates that the connection is down due to some network I/O error.
 | 
				
			||||||
	errNetworkIO = errors.New("grpc: failed with network I/O error")
 | 
						errNetworkIO = errors.New("grpc: failed with network I/O error")
 | 
				
			||||||
	// errConnDrain indicates that the connection starts to be drained and does not accept any new RPCs.
 | 
						// errConnDrain indicates that the connection starts to be drained and does not accept any new RPCs.
 | 
				
			||||||
	errConnDrain = errors.New("grpc: the connection is drained")
 | 
						errConnDrain = errors.New("grpc: the connection is drained")
 | 
				
			||||||
	// errConnClosing indicates that the connection is closing.
 | 
						// errConnClosing indicates that the connection is closing.
 | 
				
			||||||
	errConnClosing = errors.New("grpc: the connection is closing")
 | 
						errConnClosing = errors.New("grpc: the connection is closing")
 | 
				
			||||||
 | 
						// errConnUnavailable indicates that the connection is unavailable.
 | 
				
			||||||
 | 
						errConnUnavailable = errors.New("grpc: the connection is unavailable")
 | 
				
			||||||
	errNoAddr          = errors.New("grpc: there is no address available to dial")
 | 
						errNoAddr          = errors.New("grpc: there is no address available to dial")
 | 
				
			||||||
	// minimum time to give a connection to complete
 | 
						// minimum time to give a connection to complete
 | 
				
			||||||
	minConnectTimeout = 20 * time.Second
 | 
						minConnectTimeout = 20 * time.Second
 | 
				
			||||||
@@ -196,9 +197,14 @@ func WithTimeout(d time.Duration) DialOption {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// WithDialer returns a DialOption that specifies a function to use for dialing network addresses.
 | 
					// WithDialer returns a DialOption that specifies a function to use for dialing network addresses.
 | 
				
			||||||
func WithDialer(f func(addr string, timeout time.Duration) (net.Conn, error)) DialOption {
 | 
					func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption {
 | 
				
			||||||
	return func(o *dialOptions) {
 | 
						return func(o *dialOptions) {
 | 
				
			||||||
		o.copts.Dialer = f
 | 
							o.copts.Dialer = func(ctx context.Context, addr string) (net.Conn, error) {
 | 
				
			||||||
 | 
								if deadline, ok := ctx.Deadline(); ok {
 | 
				
			||||||
 | 
									return f(addr, deadline.Sub(time.Now()))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return f(addr, 0)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -209,12 +215,19 @@ func WithUserAgent(s string) DialOption {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Dial creates a client connection the given target.
 | 
					// Dial creates a client connection to the given target.
 | 
				
			||||||
func Dial(target string, opts ...DialOption) (*ClientConn, error) {
 | 
					func Dial(target string, opts ...DialOption) (*ClientConn, error) {
 | 
				
			||||||
 | 
						return DialContext(context.Background(), target, opts...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DialContext creates a client connection to the given target
 | 
				
			||||||
 | 
					// using the supplied context.
 | 
				
			||||||
 | 
					func DialContext(ctx context.Context, target string, opts ...DialOption) (*ClientConn, error) {
 | 
				
			||||||
	cc := &ClientConn{
 | 
						cc := &ClientConn{
 | 
				
			||||||
		target: target,
 | 
							target: target,
 | 
				
			||||||
		conns:  make(map[Address]*addrConn),
 | 
							conns:  make(map[Address]*addrConn),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						cc.ctx, cc.cancel = context.WithCancel(ctx)
 | 
				
			||||||
	for _, opt := range opts {
 | 
						for _, opt := range opts {
 | 
				
			||||||
		opt(&cc.dopts)
 | 
							opt(&cc.dopts)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -226,17 +239,18 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
 | 
				
			|||||||
	if cc.dopts.bs == nil {
 | 
						if cc.dopts.bs == nil {
 | 
				
			||||||
		cc.dopts.bs = DefaultBackoffConfig
 | 
							cc.dopts.bs = DefaultBackoffConfig
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if cc.dopts.balancer == nil {
 | 
					 | 
				
			||||||
		cc.dopts.balancer = RoundRobin(nil)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := cc.dopts.balancer.Start(target); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		ok    bool
 | 
							ok    bool
 | 
				
			||||||
		addrs []Address
 | 
							addrs []Address
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
						if cc.dopts.balancer == nil {
 | 
				
			||||||
 | 
							// Connect to target directly if balancer is nil.
 | 
				
			||||||
 | 
							addrs = append(addrs, Address{Addr: target})
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if err := cc.dopts.balancer.Start(target); err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ch := cc.dopts.balancer.Notify()
 | 
							ch := cc.dopts.balancer.Notify()
 | 
				
			||||||
		if ch == nil {
 | 
							if ch == nil {
 | 
				
			||||||
			// There is no name resolver installed.
 | 
								// There is no name resolver installed.
 | 
				
			||||||
@@ -247,10 +261,11 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
 | 
				
			|||||||
				return nil, errNoAddr
 | 
									return nil, errNoAddr
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	waitC := make(chan error, 1)
 | 
						waitC := make(chan error, 1)
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		for _, a := range addrs {
 | 
							for _, a := range addrs {
 | 
				
			||||||
			if err := cc.newAddrConn(a, false); err != nil {
 | 
								if err := cc.resetAddrConn(a, false, nil); err != nil {
 | 
				
			||||||
				waitC <- err
 | 
									waitC <- err
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -267,10 +282,15 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
 | 
				
			|||||||
			cc.Close()
 | 
								cc.Close()
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						case <-cc.ctx.Done():
 | 
				
			||||||
 | 
							cc.Close()
 | 
				
			||||||
 | 
							return nil, cc.ctx.Err()
 | 
				
			||||||
	case <-timeoutCh:
 | 
						case <-timeoutCh:
 | 
				
			||||||
		cc.Close()
 | 
							cc.Close()
 | 
				
			||||||
		return nil, ErrClientConnTimeout
 | 
							return nil, ErrClientConnTimeout
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// If balancer is nil or balancer.Notify() is nil, ok will be false here.
 | 
				
			||||||
 | 
						// The lbWatcher goroutine will not be created.
 | 
				
			||||||
	if ok {
 | 
						if ok {
 | 
				
			||||||
		go cc.lbWatcher()
 | 
							go cc.lbWatcher()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -317,6 +337,9 @@ func (s ConnectivityState) String() string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ClientConn represents a client connection to an RPC server.
 | 
					// ClientConn represents a client connection to an RPC server.
 | 
				
			||||||
type ClientConn struct {
 | 
					type ClientConn struct {
 | 
				
			||||||
 | 
						ctx    context.Context
 | 
				
			||||||
 | 
						cancel context.CancelFunc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	target    string
 | 
						target    string
 | 
				
			||||||
	authority string
 | 
						authority string
 | 
				
			||||||
	dopts     dialOptions
 | 
						dopts     dialOptions
 | 
				
			||||||
@@ -347,11 +370,12 @@ func (cc *ClientConn) lbWatcher() {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			if !keep {
 | 
								if !keep {
 | 
				
			||||||
				del = append(del, c)
 | 
									del = append(del, c)
 | 
				
			||||||
 | 
									delete(cc.conns, c.addr)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		cc.mu.Unlock()
 | 
							cc.mu.Unlock()
 | 
				
			||||||
		for _, a := range add {
 | 
							for _, a := range add {
 | 
				
			||||||
			cc.newAddrConn(a, true)
 | 
								cc.resetAddrConn(a, true, nil)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for _, c := range del {
 | 
							for _, c := range del {
 | 
				
			||||||
			c.tearDown(errConnDrain)
 | 
								c.tearDown(errConnDrain)
 | 
				
			||||||
@@ -359,13 +383,17 @@ func (cc *ClientConn) lbWatcher() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cc *ClientConn) newAddrConn(addr Address, skipWait bool) error {
 | 
					// resetAddrConn creates an addrConn for addr and adds it to cc.conns.
 | 
				
			||||||
 | 
					// If there is an old addrConn for addr, it will be torn down, using tearDownErr as the reason.
 | 
				
			||||||
 | 
					// If tearDownErr is nil, errConnDrain will be used instead.
 | 
				
			||||||
 | 
					func (cc *ClientConn) resetAddrConn(addr Address, skipWait bool, tearDownErr error) error {
 | 
				
			||||||
	ac := &addrConn{
 | 
						ac := &addrConn{
 | 
				
			||||||
		cc:    cc,
 | 
							cc:    cc,
 | 
				
			||||||
		addr:  addr,
 | 
							addr:  addr,
 | 
				
			||||||
		dopts: cc.dopts,
 | 
							dopts: cc.dopts,
 | 
				
			||||||
		shutdownChan: make(chan struct{}),
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ac.ctx, ac.cancel = context.WithCancel(cc.ctx)
 | 
				
			||||||
 | 
						ac.stateCV = sync.NewCond(&ac.mu)
 | 
				
			||||||
	if EnableTracing {
 | 
						if EnableTracing {
 | 
				
			||||||
		ac.events = trace.NewEventLog("grpc.ClientConn", ac.addr.Addr)
 | 
							ac.events = trace.NewEventLog("grpc.ClientConn", ac.addr.Addr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -383,26 +411,44 @@ func (cc *ClientConn) newAddrConn(addr Address, skipWait bool) error {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Insert ac into ac.cc.conns. This needs to be done before any getTransport(...) is called.
 | 
						// Track ac in cc. This needs to be done before any getTransport(...) is called.
 | 
				
			||||||
	ac.cc.mu.Lock()
 | 
						cc.mu.Lock()
 | 
				
			||||||
	if ac.cc.conns == nil {
 | 
						if cc.conns == nil {
 | 
				
			||||||
		ac.cc.mu.Unlock()
 | 
							cc.mu.Unlock()
 | 
				
			||||||
		return ErrClientConnClosing
 | 
							return ErrClientConnClosing
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	stale := ac.cc.conns[ac.addr]
 | 
						stale := cc.conns[ac.addr]
 | 
				
			||||||
	ac.cc.conns[ac.addr] = ac
 | 
						cc.conns[ac.addr] = ac
 | 
				
			||||||
	ac.cc.mu.Unlock()
 | 
						cc.mu.Unlock()
 | 
				
			||||||
	if stale != nil {
 | 
						if stale != nil {
 | 
				
			||||||
		// There is an addrConn alive on ac.addr already. This could be due to
 | 
							// There is an addrConn alive on ac.addr already. This could be due to
 | 
				
			||||||
		// i) stale's Close is undergoing;
 | 
							// 1) a buggy Balancer notifies duplicated Addresses;
 | 
				
			||||||
		// ii) a buggy Balancer notifies duplicated Addresses.
 | 
							// 2) goaway was received, a new ac will replace the old ac.
 | 
				
			||||||
 | 
							//    The old ac should be deleted from cc.conns, but the
 | 
				
			||||||
 | 
							//    underlying transport should drain rather than close.
 | 
				
			||||||
 | 
							if tearDownErr == nil {
 | 
				
			||||||
 | 
								// tearDownErr is nil if resetAddrConn is called by
 | 
				
			||||||
 | 
								// 1) Dial
 | 
				
			||||||
 | 
								// 2) lbWatcher
 | 
				
			||||||
 | 
								// In both cases, the stale ac should drain, not close.
 | 
				
			||||||
			stale.tearDown(errConnDrain)
 | 
								stale.tearDown(errConnDrain)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								stale.tearDown(tearDownErr)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ac.stateCV = sync.NewCond(&ac.mu)
 | 
					 | 
				
			||||||
	// skipWait may overwrite the decision in ac.dopts.block.
 | 
						// skipWait may overwrite the decision in ac.dopts.block.
 | 
				
			||||||
	if ac.dopts.block && !skipWait {
 | 
						if ac.dopts.block && !skipWait {
 | 
				
			||||||
		if err := ac.resetTransport(false); err != nil {
 | 
							if err := ac.resetTransport(false); err != nil {
 | 
				
			||||||
 | 
								if err != errConnClosing {
 | 
				
			||||||
 | 
									// Tear down ac and delete it from cc.conns.
 | 
				
			||||||
 | 
									cc.mu.Lock()
 | 
				
			||||||
 | 
									delete(cc.conns, ac.addr)
 | 
				
			||||||
 | 
									cc.mu.Unlock()
 | 
				
			||||||
				ac.tearDown(err)
 | 
									ac.tearDown(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if e, ok := err.(transport.ConnectionError); ok && !e.Temporary() {
 | 
				
			||||||
 | 
									return e.Origin()
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Start to monitor the error status of transport.
 | 
							// Start to monitor the error status of transport.
 | 
				
			||||||
@@ -412,7 +458,10 @@ func (cc *ClientConn) newAddrConn(addr Address, skipWait bool) error {
 | 
				
			|||||||
		go func() {
 | 
							go func() {
 | 
				
			||||||
			if err := ac.resetTransport(false); err != nil {
 | 
								if err := ac.resetTransport(false); err != nil {
 | 
				
			||||||
				grpclog.Printf("Failed to dial %s: %v; please retry.", ac.addr.Addr, err)
 | 
									grpclog.Printf("Failed to dial %s: %v; please retry.", ac.addr.Addr, err)
 | 
				
			||||||
 | 
									if err != errConnClosing {
 | 
				
			||||||
 | 
										// Keep this ac in cc.conns, to get the reason it's torn down.
 | 
				
			||||||
					ac.tearDown(err)
 | 
										ac.tearDown(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ac.transportMonitor()
 | 
								ac.transportMonitor()
 | 
				
			||||||
@@ -422,7 +471,30 @@ func (cc *ClientConn) newAddrConn(addr Address, skipWait bool) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions) (transport.ClientTransport, func(), error) {
 | 
					func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions) (transport.ClientTransport, func(), error) {
 | 
				
			||||||
	addr, put, err := cc.dopts.balancer.Get(ctx, opts)
 | 
						var (
 | 
				
			||||||
 | 
							ac  *addrConn
 | 
				
			||||||
 | 
							ok  bool
 | 
				
			||||||
 | 
							put func()
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						if cc.dopts.balancer == nil {
 | 
				
			||||||
 | 
							// If balancer is nil, there should be only one addrConn available.
 | 
				
			||||||
 | 
							cc.mu.RLock()
 | 
				
			||||||
 | 
							if cc.conns == nil {
 | 
				
			||||||
 | 
								cc.mu.RUnlock()
 | 
				
			||||||
 | 
								return nil, nil, toRPCErr(ErrClientConnClosing)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for _, ac = range cc.conns {
 | 
				
			||||||
 | 
								// Break after the first iteration to get the first addrConn.
 | 
				
			||||||
 | 
								ok = true
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							cc.mu.RUnlock()
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							var (
 | 
				
			||||||
 | 
								addr Address
 | 
				
			||||||
 | 
								err  error
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							addr, put, err = cc.dopts.balancer.Get(ctx, opts)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, nil, toRPCErr(err)
 | 
								return nil, nil, toRPCErr(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -431,15 +503,16 @@ func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions)
 | 
				
			|||||||
			cc.mu.RUnlock()
 | 
								cc.mu.RUnlock()
 | 
				
			||||||
			return nil, nil, toRPCErr(ErrClientConnClosing)
 | 
								return nil, nil, toRPCErr(ErrClientConnClosing)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	ac, ok := cc.conns[addr]
 | 
							ac, ok = cc.conns[addr]
 | 
				
			||||||
		cc.mu.RUnlock()
 | 
							cc.mu.RUnlock()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		if put != nil {
 | 
							if put != nil {
 | 
				
			||||||
			put()
 | 
								put()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nil, nil, Errorf(codes.Internal, "grpc: failed to find the transport to send the rpc")
 | 
							return nil, nil, errConnClosing
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	t, err := ac.wait(ctx, !opts.BlockingWait)
 | 
						t, err := ac.wait(ctx, cc.dopts.balancer != nil, !opts.BlockingWait)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if put != nil {
 | 
							if put != nil {
 | 
				
			||||||
			put()
 | 
								put()
 | 
				
			||||||
@@ -451,6 +524,8 @@ func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Close tears down the ClientConn and all underlying connections.
 | 
					// Close tears down the ClientConn and all underlying connections.
 | 
				
			||||||
func (cc *ClientConn) Close() error {
 | 
					func (cc *ClientConn) Close() error {
 | 
				
			||||||
 | 
						cc.cancel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cc.mu.Lock()
 | 
						cc.mu.Lock()
 | 
				
			||||||
	if cc.conns == nil {
 | 
						if cc.conns == nil {
 | 
				
			||||||
		cc.mu.Unlock()
 | 
							cc.mu.Unlock()
 | 
				
			||||||
@@ -459,7 +534,9 @@ func (cc *ClientConn) Close() error {
 | 
				
			|||||||
	conns := cc.conns
 | 
						conns := cc.conns
 | 
				
			||||||
	cc.conns = nil
 | 
						cc.conns = nil
 | 
				
			||||||
	cc.mu.Unlock()
 | 
						cc.mu.Unlock()
 | 
				
			||||||
 | 
						if cc.dopts.balancer != nil {
 | 
				
			||||||
		cc.dopts.balancer.Close()
 | 
							cc.dopts.balancer.Close()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	for _, ac := range conns {
 | 
						for _, ac := range conns {
 | 
				
			||||||
		ac.tearDown(ErrClientConnClosing)
 | 
							ac.tearDown(ErrClientConnClosing)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -468,10 +545,12 @@ func (cc *ClientConn) Close() error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// addrConn is a network connection to a given address.
 | 
					// addrConn is a network connection to a given address.
 | 
				
			||||||
type addrConn struct {
 | 
					type addrConn struct {
 | 
				
			||||||
 | 
						ctx    context.Context
 | 
				
			||||||
 | 
						cancel context.CancelFunc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cc     *ClientConn
 | 
						cc     *ClientConn
 | 
				
			||||||
	addr   Address
 | 
						addr   Address
 | 
				
			||||||
	dopts  dialOptions
 | 
						dopts  dialOptions
 | 
				
			||||||
	shutdownChan chan struct{}
 | 
					 | 
				
			||||||
	events trace.EventLog
 | 
						events trace.EventLog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mu      sync.Mutex
 | 
						mu      sync.Mutex
 | 
				
			||||||
@@ -482,6 +561,9 @@ type addrConn struct {
 | 
				
			|||||||
	// due to timeout.
 | 
						// due to timeout.
 | 
				
			||||||
	ready     chan struct{}
 | 
						ready     chan struct{}
 | 
				
			||||||
	transport transport.ClientTransport
 | 
						transport transport.ClientTransport
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The reason this addrConn is torn down.
 | 
				
			||||||
 | 
						tearDownErr error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// printf records an event in ac's event log, unless ac has been closed.
 | 
					// printf records an event in ac's event log, unless ac has been closed.
 | 
				
			||||||
@@ -537,8 +619,7 @@ func (ac *addrConn) waitForStateChange(ctx context.Context, sourceState Connecti
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ac *addrConn) resetTransport(closeTransport bool) error {
 | 
					func (ac *addrConn) resetTransport(closeTransport bool) error {
 | 
				
			||||||
	var retries int
 | 
						for retries := 0; ; retries++ {
 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		ac.mu.Lock()
 | 
							ac.mu.Lock()
 | 
				
			||||||
		ac.printf("connecting")
 | 
							ac.printf("connecting")
 | 
				
			||||||
		if ac.state == Shutdown {
 | 
							if ac.state == Shutdown {
 | 
				
			||||||
@@ -558,13 +639,20 @@ func (ac *addrConn) resetTransport(closeTransport bool) error {
 | 
				
			|||||||
			t.Close()
 | 
								t.Close()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		sleepTime := ac.dopts.bs.backoff(retries)
 | 
							sleepTime := ac.dopts.bs.backoff(retries)
 | 
				
			||||||
		ac.dopts.copts.Timeout = sleepTime
 | 
							timeout := minConnectTimeout
 | 
				
			||||||
		if sleepTime < minConnectTimeout {
 | 
							if timeout < sleepTime {
 | 
				
			||||||
			ac.dopts.copts.Timeout = minConnectTimeout
 | 
								timeout = sleepTime
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							ctx, cancel := context.WithTimeout(ac.ctx, timeout)
 | 
				
			||||||
		connectTime := time.Now()
 | 
							connectTime := time.Now()
 | 
				
			||||||
		newTransport, err := transport.NewClientTransport(ac.addr.Addr, &ac.dopts.copts)
 | 
							newTransport, err := transport.NewClientTransport(ctx, ac.addr.Addr, ac.dopts.copts)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								cancel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if e, ok := err.(transport.ConnectionError); ok && !e.Temporary() {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								grpclog.Printf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, ac.addr)
 | 
				
			||||||
			ac.mu.Lock()
 | 
								ac.mu.Lock()
 | 
				
			||||||
			if ac.state == Shutdown {
 | 
								if ac.state == Shutdown {
 | 
				
			||||||
				// ac.tearDown(...) has been invoked.
 | 
									// ac.tearDown(...) has been invoked.
 | 
				
			||||||
@@ -579,17 +667,12 @@ func (ac *addrConn) resetTransport(closeTransport bool) error {
 | 
				
			|||||||
				ac.ready = nil
 | 
									ac.ready = nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ac.mu.Unlock()
 | 
								ac.mu.Unlock()
 | 
				
			||||||
			sleepTime -= time.Since(connectTime)
 | 
					 | 
				
			||||||
			if sleepTime < 0 {
 | 
					 | 
				
			||||||
				sleepTime = 0
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			closeTransport = false
 | 
								closeTransport = false
 | 
				
			||||||
			select {
 | 
								select {
 | 
				
			||||||
			case <-time.After(sleepTime):
 | 
								case <-time.After(sleepTime - time.Since(connectTime)):
 | 
				
			||||||
			case <-ac.shutdownChan:
 | 
								case <-ac.ctx.Done():
 | 
				
			||||||
 | 
									return ac.ctx.Err()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			retries++
 | 
					 | 
				
			||||||
			grpclog.Printf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, ac.addr)
 | 
					 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ac.mu.Lock()
 | 
							ac.mu.Lock()
 | 
				
			||||||
@@ -607,7 +690,9 @@ func (ac *addrConn) resetTransport(closeTransport bool) error {
 | 
				
			|||||||
			close(ac.ready)
 | 
								close(ac.ready)
 | 
				
			||||||
			ac.ready = nil
 | 
								ac.ready = nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if ac.cc.dopts.balancer != nil {
 | 
				
			||||||
			ac.down = ac.cc.dopts.balancer.Up(ac.addr)
 | 
								ac.down = ac.cc.dopts.balancer.Up(ac.addr)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ac.mu.Unlock()
 | 
							ac.mu.Unlock()
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -621,14 +706,42 @@ func (ac *addrConn) transportMonitor() {
 | 
				
			|||||||
		t := ac.transport
 | 
							t := ac.transport
 | 
				
			||||||
		ac.mu.Unlock()
 | 
							ac.mu.Unlock()
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		// shutdownChan is needed to detect the teardown when
 | 
							// This is needed to detect the teardown when
 | 
				
			||||||
		// the addrConn is idle (i.e., no RPC in flight).
 | 
							// the addrConn is idle (i.e., no RPC in flight).
 | 
				
			||||||
		case <-ac.shutdownChan:
 | 
							case <-ac.ctx.Done():
 | 
				
			||||||
 | 
								select {
 | 
				
			||||||
 | 
								case <-t.Error():
 | 
				
			||||||
 | 
									t.Close()
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							case <-t.GoAway():
 | 
				
			||||||
 | 
								// If GoAway happens without any network I/O error, ac is closed without shutting down the
 | 
				
			||||||
 | 
								// underlying transport (the transport will be closed when all the pending RPCs finished or
 | 
				
			||||||
 | 
								// failed.).
 | 
				
			||||||
 | 
								// If GoAway and some network I/O error happen concurrently, ac and its underlying transport
 | 
				
			||||||
 | 
								// are closed.
 | 
				
			||||||
 | 
								// In both cases, a new ac is created.
 | 
				
			||||||
 | 
								select {
 | 
				
			||||||
 | 
								case <-t.Error():
 | 
				
			||||||
 | 
									ac.cc.resetAddrConn(ac.addr, true, errNetworkIO)
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									ac.cc.resetAddrConn(ac.addr, true, errConnDrain)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		case <-t.Error():
 | 
							case <-t.Error():
 | 
				
			||||||
 | 
								select {
 | 
				
			||||||
 | 
								case <-ac.ctx.Done():
 | 
				
			||||||
 | 
									t.Close()
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								case <-t.GoAway():
 | 
				
			||||||
 | 
									ac.cc.resetAddrConn(ac.addr, true, errNetworkIO)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			ac.mu.Lock()
 | 
								ac.mu.Lock()
 | 
				
			||||||
			if ac.state == Shutdown {
 | 
								if ac.state == Shutdown {
 | 
				
			||||||
				// ac.tearDown(...) has been invoked.
 | 
									// ac has been shutdown.
 | 
				
			||||||
				ac.mu.Unlock()
 | 
									ac.mu.Unlock()
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -640,6 +753,10 @@ func (ac *addrConn) transportMonitor() {
 | 
				
			|||||||
				ac.printf("transport exiting: %v", err)
 | 
									ac.printf("transport exiting: %v", err)
 | 
				
			||||||
				ac.mu.Unlock()
 | 
									ac.mu.Unlock()
 | 
				
			||||||
				grpclog.Printf("grpc: addrConn.transportMonitor exits due to: %v", err)
 | 
									grpclog.Printf("grpc: addrConn.transportMonitor exits due to: %v", err)
 | 
				
			||||||
 | 
									if err != errConnClosing {
 | 
				
			||||||
 | 
										// Keep this ac in cc.conns, to get the reason it's torn down.
 | 
				
			||||||
 | 
										ac.tearDown(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -647,22 +764,30 @@ func (ac *addrConn) transportMonitor() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// wait blocks until i) the new transport is up or ii) ctx is done or iii) ac is closed or
 | 
					// wait blocks until i) the new transport is up or ii) ctx is done or iii) ac is closed or
 | 
				
			||||||
// iv) transport is in TransientFailure and the RPC is fail-fast.
 | 
					// iv) transport is in TransientFailure and there's no balancer/failfast is true.
 | 
				
			||||||
func (ac *addrConn) wait(ctx context.Context, failFast bool) (transport.ClientTransport, error) {
 | 
					func (ac *addrConn) wait(ctx context.Context, hasBalancer, failfast bool) (transport.ClientTransport, error) {
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		ac.mu.Lock()
 | 
							ac.mu.Lock()
 | 
				
			||||||
		switch {
 | 
							switch {
 | 
				
			||||||
		case ac.state == Shutdown:
 | 
							case ac.state == Shutdown:
 | 
				
			||||||
 | 
								if failfast || !hasBalancer {
 | 
				
			||||||
 | 
									// RPC is failfast or balancer is nil. This RPC should fail with ac.tearDownErr.
 | 
				
			||||||
 | 
									err := ac.tearDownErr
 | 
				
			||||||
 | 
									ac.mu.Unlock()
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			ac.mu.Unlock()
 | 
								ac.mu.Unlock()
 | 
				
			||||||
			return nil, errConnClosing
 | 
								return nil, errConnClosing
 | 
				
			||||||
		case ac.state == Ready:
 | 
							case ac.state == Ready:
 | 
				
			||||||
			ct := ac.transport
 | 
								ct := ac.transport
 | 
				
			||||||
			ac.mu.Unlock()
 | 
								ac.mu.Unlock()
 | 
				
			||||||
			return ct, nil
 | 
								return ct, nil
 | 
				
			||||||
		case ac.state == TransientFailure && failFast:
 | 
							case ac.state == TransientFailure:
 | 
				
			||||||
 | 
								if failfast || hasBalancer {
 | 
				
			||||||
				ac.mu.Unlock()
 | 
									ac.mu.Unlock()
 | 
				
			||||||
			return nil, Errorf(codes.Unavailable, "grpc: RPC failed fast due to transport failure")
 | 
									return nil, errConnUnavailable
 | 
				
			||||||
		default:
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ready := ac.ready
 | 
							ready := ac.ready
 | 
				
			||||||
		if ready == nil {
 | 
							if ready == nil {
 | 
				
			||||||
			ready = make(chan struct{})
 | 
								ready = make(chan struct{})
 | 
				
			||||||
@@ -676,31 +801,34 @@ func (ac *addrConn) wait(ctx context.Context, failFast bool) (transport.ClientTr
 | 
				
			|||||||
		case <-ready:
 | 
							case <-ready:
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// tearDown starts to tear down the addrConn.
 | 
					// tearDown starts to tear down the addrConn.
 | 
				
			||||||
// TODO(zhaoq): Make this synchronous to avoid unbounded memory consumption in
 | 
					// TODO(zhaoq): Make this synchronous to avoid unbounded memory consumption in
 | 
				
			||||||
// some edge cases (e.g., the caller opens and closes many addrConn's in a
 | 
					// some edge cases (e.g., the caller opens and closes many addrConn's in a
 | 
				
			||||||
// tight loop.
 | 
					// tight loop.
 | 
				
			||||||
 | 
					// tearDown doesn't remove ac from ac.cc.conns.
 | 
				
			||||||
func (ac *addrConn) tearDown(err error) {
 | 
					func (ac *addrConn) tearDown(err error) {
 | 
				
			||||||
 | 
						ac.cancel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ac.mu.Lock()
 | 
						ac.mu.Lock()
 | 
				
			||||||
	defer func() {
 | 
						defer ac.mu.Unlock()
 | 
				
			||||||
		ac.mu.Unlock()
 | 
					 | 
				
			||||||
		ac.cc.mu.Lock()
 | 
					 | 
				
			||||||
		if ac.cc.conns != nil {
 | 
					 | 
				
			||||||
			delete(ac.cc.conns, ac.addr)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		ac.cc.mu.Unlock()
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	if ac.state == Shutdown {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ac.state = Shutdown
 | 
					 | 
				
			||||||
	if ac.down != nil {
 | 
						if ac.down != nil {
 | 
				
			||||||
		ac.down(downErrorf(false, false, "%v", err))
 | 
							ac.down(downErrorf(false, false, "%v", err))
 | 
				
			||||||
		ac.down = nil
 | 
							ac.down = nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if err == errConnDrain && ac.transport != nil {
 | 
				
			||||||
 | 
							// GracefulClose(...) may be executed multiple times when
 | 
				
			||||||
 | 
							// i) receiving multiple GoAway frames from the server; or
 | 
				
			||||||
 | 
							// ii) there are concurrent name resolver/Balancer triggered
 | 
				
			||||||
 | 
							// address removal and GoAway.
 | 
				
			||||||
 | 
							ac.transport.GracefulClose()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if ac.state == Shutdown {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ac.state = Shutdown
 | 
				
			||||||
 | 
						ac.tearDownErr = err
 | 
				
			||||||
	ac.stateCV.Broadcast()
 | 
						ac.stateCV.Broadcast()
 | 
				
			||||||
	if ac.events != nil {
 | 
						if ac.events != nil {
 | 
				
			||||||
		ac.events.Finish()
 | 
							ac.events.Finish()
 | 
				
			||||||
@@ -710,15 +838,8 @@ func (ac *addrConn) tearDown(err error) {
 | 
				
			|||||||
		close(ac.ready)
 | 
							close(ac.ready)
 | 
				
			||||||
		ac.ready = nil
 | 
							ac.ready = nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ac.transport != nil {
 | 
						if ac.transport != nil && err != errConnDrain {
 | 
				
			||||||
		if err == errConnDrain {
 | 
					 | 
				
			||||||
			ac.transport.GracefulClose()
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
		ac.transport.Close()
 | 
							ac.transport.Close()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ac.shutdownChan != nil {
 | 
					 | 
				
			||||||
		close(ac.shutdownChan)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										43
									
								
								vendor/google.golang.org/grpc/credentials/credentials.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/google.golang.org/grpc/credentials/credentials.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -44,7 +44,6 @@ import (
 | 
				
			|||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"golang.org/x/net/context"
 | 
						"golang.org/x/net/context"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -93,11 +92,12 @@ type TransportCredentials interface {
 | 
				
			|||||||
	// ClientHandshake does the authentication handshake specified by the corresponding
 | 
						// ClientHandshake does the authentication handshake specified by the corresponding
 | 
				
			||||||
	// authentication protocol on rawConn for clients. It returns the authenticated
 | 
						// authentication protocol on rawConn for clients. It returns the authenticated
 | 
				
			||||||
	// connection and the corresponding auth information about the connection.
 | 
						// connection and the corresponding auth information about the connection.
 | 
				
			||||||
	ClientHandshake(addr string, rawConn net.Conn, timeout time.Duration) (net.Conn, AuthInfo, error)
 | 
						// Implementations must use the provided context to implement timely cancellation.
 | 
				
			||||||
 | 
						ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
 | 
				
			||||||
	// ServerHandshake does the authentication handshake for servers. It returns
 | 
						// ServerHandshake does the authentication handshake for servers. It returns
 | 
				
			||||||
	// the authenticated connection and the corresponding auth information about
 | 
						// the authenticated connection and the corresponding auth information about
 | 
				
			||||||
	// the connection.
 | 
						// the connection.
 | 
				
			||||||
	ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error)
 | 
						ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
 | 
				
			||||||
	// Info provides the ProtocolInfo of this TransportCredentials.
 | 
						// Info provides the ProtocolInfo of this TransportCredentials.
 | 
				
			||||||
	Info() ProtocolInfo
 | 
						Info() ProtocolInfo
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -136,43 +136,29 @@ func (c *tlsCreds) RequireTransportSecurity() bool {
 | 
				
			|||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type timeoutError struct{}
 | 
					func (c *tlsCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (_ net.Conn, _ AuthInfo, err error) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
func (timeoutError) Error() string   { return "credentials: Dial timed out" }
 | 
					 | 
				
			||||||
func (timeoutError) Timeout() bool   { return true }
 | 
					 | 
				
			||||||
func (timeoutError) Temporary() bool { return true }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *tlsCreds) ClientHandshake(addr string, rawConn net.Conn, timeout time.Duration) (_ net.Conn, _ AuthInfo, err error) {
 | 
					 | 
				
			||||||
	// borrow some code from tls.DialWithDialer
 | 
					 | 
				
			||||||
	var errChannel chan error
 | 
					 | 
				
			||||||
	if timeout != 0 {
 | 
					 | 
				
			||||||
		errChannel = make(chan error, 2)
 | 
					 | 
				
			||||||
		time.AfterFunc(timeout, func() {
 | 
					 | 
				
			||||||
			errChannel <- timeoutError{}
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// use local cfg to avoid clobbering ServerName if using multiple endpoints
 | 
						// use local cfg to avoid clobbering ServerName if using multiple endpoints
 | 
				
			||||||
	cfg := *c.config
 | 
						cfg := cloneTLSConfig(c.config)
 | 
				
			||||||
	if c.config.ServerName == "" {
 | 
						if cfg.ServerName == "" {
 | 
				
			||||||
		colonPos := strings.LastIndex(addr, ":")
 | 
							colonPos := strings.LastIndex(addr, ":")
 | 
				
			||||||
		if colonPos == -1 {
 | 
							if colonPos == -1 {
 | 
				
			||||||
			colonPos = len(addr)
 | 
								colonPos = len(addr)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		cfg.ServerName = addr[:colonPos]
 | 
							cfg.ServerName = addr[:colonPos]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	conn := tls.Client(rawConn, &cfg)
 | 
						conn := tls.Client(rawConn, cfg)
 | 
				
			||||||
	if timeout == 0 {
 | 
						errChannel := make(chan error, 1)
 | 
				
			||||||
		err = conn.Handshake()
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		errChannel <- conn.Handshake()
 | 
							errChannel <- conn.Handshake()
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
		err = <-errChannel
 | 
						select {
 | 
				
			||||||
	}
 | 
						case err := <-errChannel:
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
		rawConn.Close()
 | 
					 | 
				
			||||||
			return nil, nil, err
 | 
								return nil, nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						case <-ctx.Done():
 | 
				
			||||||
 | 
							return nil, nil, ctx.Err()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// TODO(zhaoq): Omit the auth info for client now. It is more for
 | 
						// TODO(zhaoq): Omit the auth info for client now. It is more for
 | 
				
			||||||
	// information than anything else.
 | 
						// information than anything else.
 | 
				
			||||||
	return conn, nil, nil
 | 
						return conn, nil, nil
 | 
				
			||||||
@@ -181,7 +167,6 @@ func (c *tlsCreds) ClientHandshake(addr string, rawConn net.Conn, timeout time.D
 | 
				
			|||||||
func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) {
 | 
					func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) {
 | 
				
			||||||
	conn := tls.Server(rawConn, c.config)
 | 
						conn := tls.Server(rawConn, c.config)
 | 
				
			||||||
	if err := conn.Handshake(); err != nil {
 | 
						if err := conn.Handshake(); err != nil {
 | 
				
			||||||
		rawConn.Close()
 | 
					 | 
				
			||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return conn, TLSInfo{conn.ConnectionState()}, nil
 | 
						return conn, TLSInfo{conn.ConnectionState()}, nil
 | 
				
			||||||
@@ -189,7 +174,7 @@ func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// NewTLS uses c to construct a TransportCredentials based on TLS.
 | 
					// NewTLS uses c to construct a TransportCredentials based on TLS.
 | 
				
			||||||
func NewTLS(c *tls.Config) TransportCredentials {
 | 
					func NewTLS(c *tls.Config) TransportCredentials {
 | 
				
			||||||
	tc := &tlsCreds{c}
 | 
						tc := &tlsCreds{cloneTLSConfig(c)}
 | 
				
			||||||
	tc.config.NextProtos = alpnProtoStr
 | 
						tc.config.NextProtos = alpnProtoStr
 | 
				
			||||||
	return tc
 | 
						return tc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										76
									
								
								vendor/google.golang.org/grpc/credentials/credentials_util_go17.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								vendor/google.golang.org/grpc/credentials/credentials_util_go17.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					// +build go1.7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright 2016, Google Inc.
 | 
				
			||||||
 | 
					 * All rights reserved.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					 * modification, are permitted provided that the following conditions are
 | 
				
			||||||
 | 
					 * met:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					 * notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					 *     * Redistributions in binary form must reproduce the above
 | 
				
			||||||
 | 
					 * copyright notice, this list of conditions and the following disclaimer
 | 
				
			||||||
 | 
					 * in the documentation and/or other materials provided with the
 | 
				
			||||||
 | 
					 * distribution.
 | 
				
			||||||
 | 
					 *     * Neither the name of Google Inc. nor the names of its
 | 
				
			||||||
 | 
					 * contributors may be used to endorse or promote products derived from
 | 
				
			||||||
 | 
					 * this software without specific prior written permission.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
				
			||||||
 | 
					 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
				
			||||||
 | 
					 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
				
			||||||
 | 
					 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
				
			||||||
 | 
					 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
				
			||||||
 | 
					 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
 | 
					 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
				
			||||||
 | 
					 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package credentials
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/tls"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// cloneTLSConfig returns a shallow clone of the exported
 | 
				
			||||||
 | 
					// fields of cfg, ignoring the unexported sync.Once, which
 | 
				
			||||||
 | 
					// contains a mutex and must not be copied.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// If cfg is nil, a new zero tls.Config is returned.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// TODO replace this function with official clone function.
 | 
				
			||||||
 | 
					func cloneTLSConfig(cfg *tls.Config) *tls.Config {
 | 
				
			||||||
 | 
						if cfg == nil {
 | 
				
			||||||
 | 
							return &tls.Config{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &tls.Config{
 | 
				
			||||||
 | 
							Rand:                        cfg.Rand,
 | 
				
			||||||
 | 
							Time:                        cfg.Time,
 | 
				
			||||||
 | 
							Certificates:                cfg.Certificates,
 | 
				
			||||||
 | 
							NameToCertificate:           cfg.NameToCertificate,
 | 
				
			||||||
 | 
							GetCertificate:              cfg.GetCertificate,
 | 
				
			||||||
 | 
							RootCAs:                     cfg.RootCAs,
 | 
				
			||||||
 | 
							NextProtos:                  cfg.NextProtos,
 | 
				
			||||||
 | 
							ServerName:                  cfg.ServerName,
 | 
				
			||||||
 | 
							ClientAuth:                  cfg.ClientAuth,
 | 
				
			||||||
 | 
							ClientCAs:                   cfg.ClientCAs,
 | 
				
			||||||
 | 
							InsecureSkipVerify:          cfg.InsecureSkipVerify,
 | 
				
			||||||
 | 
							CipherSuites:                cfg.CipherSuites,
 | 
				
			||||||
 | 
							PreferServerCipherSuites:    cfg.PreferServerCipherSuites,
 | 
				
			||||||
 | 
							SessionTicketsDisabled:      cfg.SessionTicketsDisabled,
 | 
				
			||||||
 | 
							SessionTicketKey:            cfg.SessionTicketKey,
 | 
				
			||||||
 | 
							ClientSessionCache:          cfg.ClientSessionCache,
 | 
				
			||||||
 | 
							MinVersion:                  cfg.MinVersion,
 | 
				
			||||||
 | 
							MaxVersion:                  cfg.MaxVersion,
 | 
				
			||||||
 | 
							CurvePreferences:            cfg.CurvePreferences,
 | 
				
			||||||
 | 
							DynamicRecordSizingDisabled: cfg.DynamicRecordSizingDisabled,
 | 
				
			||||||
 | 
							Renegotiation:               cfg.Renegotiation,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										74
									
								
								vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					// +build !go1.7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright 2016, Google Inc.
 | 
				
			||||||
 | 
					 * All rights reserved.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					 * modification, are permitted provided that the following conditions are
 | 
				
			||||||
 | 
					 * met:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					 * notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					 *     * Redistributions in binary form must reproduce the above
 | 
				
			||||||
 | 
					 * copyright notice, this list of conditions and the following disclaimer
 | 
				
			||||||
 | 
					 * in the documentation and/or other materials provided with the
 | 
				
			||||||
 | 
					 * distribution.
 | 
				
			||||||
 | 
					 *     * Neither the name of Google Inc. nor the names of its
 | 
				
			||||||
 | 
					 * contributors may be used to endorse or promote products derived from
 | 
				
			||||||
 | 
					 * this software without specific prior written permission.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
				
			||||||
 | 
					 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
				
			||||||
 | 
					 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
				
			||||||
 | 
					 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
				
			||||||
 | 
					 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
				
			||||||
 | 
					 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
 | 
					 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
				
			||||||
 | 
					 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package credentials
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/tls"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// cloneTLSConfig returns a shallow clone of the exported
 | 
				
			||||||
 | 
					// fields of cfg, ignoring the unexported sync.Once, which
 | 
				
			||||||
 | 
					// contains a mutex and must not be copied.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// If cfg is nil, a new zero tls.Config is returned.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// TODO replace this function with official clone function.
 | 
				
			||||||
 | 
					func cloneTLSConfig(cfg *tls.Config) *tls.Config {
 | 
				
			||||||
 | 
						if cfg == nil {
 | 
				
			||||||
 | 
							return &tls.Config{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &tls.Config{
 | 
				
			||||||
 | 
							Rand:                     cfg.Rand,
 | 
				
			||||||
 | 
							Time:                     cfg.Time,
 | 
				
			||||||
 | 
							Certificates:             cfg.Certificates,
 | 
				
			||||||
 | 
							NameToCertificate:        cfg.NameToCertificate,
 | 
				
			||||||
 | 
							GetCertificate:           cfg.GetCertificate,
 | 
				
			||||||
 | 
							RootCAs:                  cfg.RootCAs,
 | 
				
			||||||
 | 
							NextProtos:               cfg.NextProtos,
 | 
				
			||||||
 | 
							ServerName:               cfg.ServerName,
 | 
				
			||||||
 | 
							ClientAuth:               cfg.ClientAuth,
 | 
				
			||||||
 | 
							ClientCAs:                cfg.ClientCAs,
 | 
				
			||||||
 | 
							InsecureSkipVerify:       cfg.InsecureSkipVerify,
 | 
				
			||||||
 | 
							CipherSuites:             cfg.CipherSuites,
 | 
				
			||||||
 | 
							PreferServerCipherSuites: cfg.PreferServerCipherSuites,
 | 
				
			||||||
 | 
							SessionTicketsDisabled:   cfg.SessionTicketsDisabled,
 | 
				
			||||||
 | 
							SessionTicketKey:         cfg.SessionTicketKey,
 | 
				
			||||||
 | 
							ClientSessionCache:       cfg.ClientSessionCache,
 | 
				
			||||||
 | 
							MinVersion:               cfg.MinVersion,
 | 
				
			||||||
 | 
							MaxVersion:               cfg.MaxVersion,
 | 
				
			||||||
 | 
							CurvePreferences:         cfg.CurvePreferences,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								vendor/google.golang.org/grpc/metadata/metadata.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/google.golang.org/grpc/metadata/metadata.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -60,15 +60,21 @@ func encodeKeyValue(k, v string) (string, string) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// DecodeKeyValue returns the original key and value corresponding to the
 | 
					// DecodeKeyValue returns the original key and value corresponding to the
 | 
				
			||||||
// encoded data in k, v.
 | 
					// encoded data in k, v.
 | 
				
			||||||
 | 
					// If k is a binary header and v contains comma, v is split on comma before decoded,
 | 
				
			||||||
 | 
					// and the decoded v will be joined with comma before returned.
 | 
				
			||||||
func DecodeKeyValue(k, v string) (string, string, error) {
 | 
					func DecodeKeyValue(k, v string) (string, string, error) {
 | 
				
			||||||
	if !strings.HasSuffix(k, binHdrSuffix) {
 | 
						if !strings.HasSuffix(k, binHdrSuffix) {
 | 
				
			||||||
		return k, v, nil
 | 
							return k, v, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	val, err := base64.StdEncoding.DecodeString(v)
 | 
						vvs := strings.Split(v, ",")
 | 
				
			||||||
 | 
						for i, vv := range vvs {
 | 
				
			||||||
 | 
							val, err := base64.StdEncoding.DecodeString(vv)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return "", "", err
 | 
								return "", "", err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	return k, string(val), nil
 | 
							vvs[i] = string(val)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return k, strings.Join(vvs, ","), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MD is a mapping from metadata keys to values. Users should use the following
 | 
					// MD is a mapping from metadata keys to values. Users should use the following
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								vendor/google.golang.org/grpc/rpc_util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/google.golang.org/grpc/rpc_util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -227,7 +227,7 @@ type parser struct {
 | 
				
			|||||||
// No other error values or types must be returned, which also means
 | 
					// No other error values or types must be returned, which also means
 | 
				
			||||||
// that the underlying io.Reader must not return an incompatible
 | 
					// that the underlying io.Reader must not return an incompatible
 | 
				
			||||||
// error.
 | 
					// error.
 | 
				
			||||||
func (p *parser) recvMsg() (pf payloadFormat, msg []byte, err error) {
 | 
					func (p *parser) recvMsg(maxMsgSize int) (pf payloadFormat, msg []byte, err error) {
 | 
				
			||||||
	if _, err := io.ReadFull(p.r, p.header[:]); err != nil {
 | 
						if _, err := io.ReadFull(p.r, p.header[:]); err != nil {
 | 
				
			||||||
		return 0, nil, err
 | 
							return 0, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -238,6 +238,9 @@ func (p *parser) recvMsg() (pf payloadFormat, msg []byte, err error) {
 | 
				
			|||||||
	if length == 0 {
 | 
						if length == 0 {
 | 
				
			||||||
		return pf, nil, nil
 | 
							return pf, nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if length > uint32(maxMsgSize) {
 | 
				
			||||||
 | 
							return 0, nil, Errorf(codes.Internal, "grpc: received message length %d exceeding the max size %d", length, maxMsgSize)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// TODO(bradfitz,zhaoq): garbage. reuse buffer after proto decoding instead
 | 
						// TODO(bradfitz,zhaoq): garbage. reuse buffer after proto decoding instead
 | 
				
			||||||
	// of making it for each message:
 | 
						// of making it for each message:
 | 
				
			||||||
	msg = make([]byte, int(length))
 | 
						msg = make([]byte, int(length))
 | 
				
			||||||
@@ -308,8 +311,8 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, dc Decompressor) er
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{}) error {
 | 
					func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{}, maxMsgSize int) error {
 | 
				
			||||||
	pf, d, err := p.recvMsg()
 | 
						pf, d, err := p.recvMsg(maxMsgSize)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -319,11 +322,16 @@ func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{
 | 
				
			|||||||
	if pf == compressionMade {
 | 
						if pf == compressionMade {
 | 
				
			||||||
		d, err = dc.Do(bytes.NewReader(d))
 | 
							d, err = dc.Do(bytes.NewReader(d))
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return transport.StreamErrorf(codes.Internal, "grpc: failed to decompress the received message %v", err)
 | 
								return Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if len(d) > maxMsgSize {
 | 
				
			||||||
 | 
							// TODO: Revisit the error code. Currently keep it consistent with java
 | 
				
			||||||
 | 
							// implementation.
 | 
				
			||||||
 | 
							return Errorf(codes.Internal, "grpc: received a message of %d bytes exceeding %d limit", len(d), maxMsgSize)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if err := c.Unmarshal(d, m); err != nil {
 | 
						if err := c.Unmarshal(d, m); err != nil {
 | 
				
			||||||
		return transport.StreamErrorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err)
 | 
							return Errorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										75
									
								
								vendor/google.golang.org/grpc/server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										75
									
								
								vendor/google.golang.org/grpc/server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -92,6 +92,10 @@ type Server struct {
 | 
				
			|||||||
	mu    sync.Mutex // guards following
 | 
						mu    sync.Mutex // guards following
 | 
				
			||||||
	lis   map[net.Listener]bool
 | 
						lis   map[net.Listener]bool
 | 
				
			||||||
	conns map[io.Closer]bool
 | 
						conns map[io.Closer]bool
 | 
				
			||||||
 | 
						drain bool
 | 
				
			||||||
 | 
						// A CondVar to let GracefulStop() blocks until all the pending RPCs are finished
 | 
				
			||||||
 | 
						// and all the transport goes away.
 | 
				
			||||||
 | 
						cv     *sync.Cond
 | 
				
			||||||
	m      map[string]*service // service name -> service info
 | 
						m      map[string]*service // service name -> service info
 | 
				
			||||||
	events trace.EventLog
 | 
						events trace.EventLog
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -101,12 +105,15 @@ type options struct {
 | 
				
			|||||||
	codec                Codec
 | 
						codec                Codec
 | 
				
			||||||
	cp                   Compressor
 | 
						cp                   Compressor
 | 
				
			||||||
	dc                   Decompressor
 | 
						dc                   Decompressor
 | 
				
			||||||
 | 
						maxMsgSize           int
 | 
				
			||||||
	unaryInt             UnaryServerInterceptor
 | 
						unaryInt             UnaryServerInterceptor
 | 
				
			||||||
	streamInt            StreamServerInterceptor
 | 
						streamInt            StreamServerInterceptor
 | 
				
			||||||
	maxConcurrentStreams uint32
 | 
						maxConcurrentStreams uint32
 | 
				
			||||||
	useHandlerImpl       bool // use http.Handler-based server
 | 
						useHandlerImpl       bool // use http.Handler-based server
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var defaultMaxMsgSize = 1024 * 1024 * 4 // use 4MB as the default message size limit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A ServerOption sets options.
 | 
					// A ServerOption sets options.
 | 
				
			||||||
type ServerOption func(*options)
 | 
					type ServerOption func(*options)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -117,20 +124,28 @@ func CustomCodec(codec Codec) ServerOption {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RPCCompressor returns a ServerOption that sets a compressor for outbound message.
 | 
					// RPCCompressor returns a ServerOption that sets a compressor for outbound messages.
 | 
				
			||||||
func RPCCompressor(cp Compressor) ServerOption {
 | 
					func RPCCompressor(cp Compressor) ServerOption {
 | 
				
			||||||
	return func(o *options) {
 | 
						return func(o *options) {
 | 
				
			||||||
		o.cp = cp
 | 
							o.cp = cp
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RPCDecompressor returns a ServerOption that sets a decompressor for inbound message.
 | 
					// RPCDecompressor returns a ServerOption that sets a decompressor for inbound messages.
 | 
				
			||||||
func RPCDecompressor(dc Decompressor) ServerOption {
 | 
					func RPCDecompressor(dc Decompressor) ServerOption {
 | 
				
			||||||
	return func(o *options) {
 | 
						return func(o *options) {
 | 
				
			||||||
		o.dc = dc
 | 
							o.dc = dc
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MaxMsgSize returns a ServerOption to set the max message size in bytes for inbound mesages.
 | 
				
			||||||
 | 
					// If this is not set, gRPC uses the default 4MB.
 | 
				
			||||||
 | 
					func MaxMsgSize(m int) ServerOption {
 | 
				
			||||||
 | 
						return func(o *options) {
 | 
				
			||||||
 | 
							o.maxMsgSize = m
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MaxConcurrentStreams returns a ServerOption that will apply a limit on the number
 | 
					// MaxConcurrentStreams returns a ServerOption that will apply a limit on the number
 | 
				
			||||||
// of concurrent streams to each ServerTransport.
 | 
					// of concurrent streams to each ServerTransport.
 | 
				
			||||||
func MaxConcurrentStreams(n uint32) ServerOption {
 | 
					func MaxConcurrentStreams(n uint32) ServerOption {
 | 
				
			||||||
@@ -173,6 +188,7 @@ func StreamInterceptor(i StreamServerInterceptor) ServerOption {
 | 
				
			|||||||
// started to accept requests yet.
 | 
					// started to accept requests yet.
 | 
				
			||||||
func NewServer(opt ...ServerOption) *Server {
 | 
					func NewServer(opt ...ServerOption) *Server {
 | 
				
			||||||
	var opts options
 | 
						var opts options
 | 
				
			||||||
 | 
						opts.maxMsgSize = defaultMaxMsgSize
 | 
				
			||||||
	for _, o := range opt {
 | 
						for _, o := range opt {
 | 
				
			||||||
		o(&opts)
 | 
							o(&opts)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -186,6 +202,7 @@ func NewServer(opt ...ServerOption) *Server {
 | 
				
			|||||||
		conns: make(map[io.Closer]bool),
 | 
							conns: make(map[io.Closer]bool),
 | 
				
			||||||
		m:     make(map[string]*service),
 | 
							m:     make(map[string]*service),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						s.cv = sync.NewCond(&s.mu)
 | 
				
			||||||
	if EnableTracing {
 | 
						if EnableTracing {
 | 
				
			||||||
		_, file, line, _ := runtime.Caller(1)
 | 
							_, file, line, _ := runtime.Caller(1)
 | 
				
			||||||
		s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line))
 | 
							s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line))
 | 
				
			||||||
@@ -264,8 +281,8 @@ type ServiceInfo struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// GetServiceInfo returns a map from service names to ServiceInfo.
 | 
					// GetServiceInfo returns a map from service names to ServiceInfo.
 | 
				
			||||||
// Service names include the package names, in the form of <package>.<service>.
 | 
					// Service names include the package names, in the form of <package>.<service>.
 | 
				
			||||||
func (s *Server) GetServiceInfo() map[string]*ServiceInfo {
 | 
					func (s *Server) GetServiceInfo() map[string]ServiceInfo {
 | 
				
			||||||
	ret := make(map[string]*ServiceInfo)
 | 
						ret := make(map[string]ServiceInfo)
 | 
				
			||||||
	for n, srv := range s.m {
 | 
						for n, srv := range s.m {
 | 
				
			||||||
		methods := make([]MethodInfo, 0, len(srv.md)+len(srv.sd))
 | 
							methods := make([]MethodInfo, 0, len(srv.md)+len(srv.sd))
 | 
				
			||||||
		for m := range srv.md {
 | 
							for m := range srv.md {
 | 
				
			||||||
@@ -283,7 +300,7 @@ func (s *Server) GetServiceInfo() map[string]*ServiceInfo {
 | 
				
			|||||||
			})
 | 
								})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret[n] = &ServiceInfo{
 | 
							ret[n] = ServiceInfo{
 | 
				
			||||||
			Methods:  methods,
 | 
								Methods:  methods,
 | 
				
			||||||
			Metadata: srv.mdata,
 | 
								Metadata: srv.mdata,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -468,7 +485,7 @@ func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Strea
 | 
				
			|||||||
func (s *Server) addConn(c io.Closer) bool {
 | 
					func (s *Server) addConn(c io.Closer) bool {
 | 
				
			||||||
	s.mu.Lock()
 | 
						s.mu.Lock()
 | 
				
			||||||
	defer s.mu.Unlock()
 | 
						defer s.mu.Unlock()
 | 
				
			||||||
	if s.conns == nil {
 | 
						if s.conns == nil || s.drain {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s.conns[c] = true
 | 
						s.conns[c] = true
 | 
				
			||||||
@@ -480,6 +497,7 @@ func (s *Server) removeConn(c io.Closer) {
 | 
				
			|||||||
	defer s.mu.Unlock()
 | 
						defer s.mu.Unlock()
 | 
				
			||||||
	if s.conns != nil {
 | 
						if s.conns != nil {
 | 
				
			||||||
		delete(s.conns, c)
 | 
							delete(s.conns, c)
 | 
				
			||||||
 | 
							s.cv.Signal()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -520,7 +538,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	p := &parser{r: stream}
 | 
						p := &parser{r: stream}
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		pf, req, err := p.recvMsg()
 | 
							pf, req, err := p.recvMsg(s.opts.maxMsgSize)
 | 
				
			||||||
		if err == io.EOF {
 | 
							if err == io.EOF {
 | 
				
			||||||
			// The entire stream is done (for unary RPC only).
 | 
								// The entire stream is done (for unary RPC only).
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
@@ -530,6 +548,10 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			switch err := err.(type) {
 | 
								switch err := err.(type) {
 | 
				
			||||||
 | 
								case *rpcError:
 | 
				
			||||||
 | 
									if err := t.WriteStatus(stream, err.code, err.desc); err != nil {
 | 
				
			||||||
 | 
										grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			case transport.ConnectionError:
 | 
								case transport.ConnectionError:
 | 
				
			||||||
				// Nothing to do here.
 | 
									// Nothing to do here.
 | 
				
			||||||
			case transport.StreamError:
 | 
								case transport.StreamError:
 | 
				
			||||||
@@ -569,6 +591,12 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
 | 
				
			|||||||
					return err
 | 
										return err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if len(req) > s.opts.maxMsgSize {
 | 
				
			||||||
 | 
									// TODO: Revisit the error code. Currently keep it consistent with
 | 
				
			||||||
 | 
									// java implementation.
 | 
				
			||||||
 | 
									statusCode = codes.Internal
 | 
				
			||||||
 | 
									statusDesc = fmt.Sprintf("grpc: server received a message of %d bytes exceeding %d limit", len(req), s.opts.maxMsgSize)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if err := s.opts.codec.Unmarshal(req, v); err != nil {
 | 
								if err := s.opts.codec.Unmarshal(req, v); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -634,6 +662,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
 | 
				
			|||||||
		codec:      s.opts.codec,
 | 
							codec:      s.opts.codec,
 | 
				
			||||||
		cp:         s.opts.cp,
 | 
							cp:         s.opts.cp,
 | 
				
			||||||
		dc:         s.opts.dc,
 | 
							dc:         s.opts.dc,
 | 
				
			||||||
 | 
							maxMsgSize: s.opts.maxMsgSize,
 | 
				
			||||||
		trInfo:     trInfo,
 | 
							trInfo:     trInfo,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ss.cp != nil {
 | 
						if ss.cp != nil {
 | 
				
			||||||
@@ -766,14 +795,16 @@ func (s *Server) Stop() {
 | 
				
			|||||||
	s.mu.Lock()
 | 
						s.mu.Lock()
 | 
				
			||||||
	listeners := s.lis
 | 
						listeners := s.lis
 | 
				
			||||||
	s.lis = nil
 | 
						s.lis = nil
 | 
				
			||||||
	cs := s.conns
 | 
						st := s.conns
 | 
				
			||||||
	s.conns = nil
 | 
						s.conns = nil
 | 
				
			||||||
 | 
						// interrupt GracefulStop if Stop and GracefulStop are called concurrently.
 | 
				
			||||||
 | 
						s.cv.Signal()
 | 
				
			||||||
	s.mu.Unlock()
 | 
						s.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for lis := range listeners {
 | 
						for lis := range listeners {
 | 
				
			||||||
		lis.Close()
 | 
							lis.Close()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for c := range cs {
 | 
						for c := range st {
 | 
				
			||||||
		c.Close()
 | 
							c.Close()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -785,6 +816,32 @@ func (s *Server) Stop() {
 | 
				
			|||||||
	s.mu.Unlock()
 | 
						s.mu.Unlock()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GracefulStop stops the gRPC server gracefully. It stops the server to accept new
 | 
				
			||||||
 | 
					// connections and RPCs and blocks until all the pending RPCs are finished.
 | 
				
			||||||
 | 
					func (s *Server) GracefulStop() {
 | 
				
			||||||
 | 
						s.mu.Lock()
 | 
				
			||||||
 | 
						defer s.mu.Unlock()
 | 
				
			||||||
 | 
						if s.drain == true || s.conns == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s.drain = true
 | 
				
			||||||
 | 
						for lis := range s.lis {
 | 
				
			||||||
 | 
							lis.Close()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s.lis = nil
 | 
				
			||||||
 | 
						for c := range s.conns {
 | 
				
			||||||
 | 
							c.(transport.ServerTransport).Drain()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for len(s.conns) != 0 {
 | 
				
			||||||
 | 
							s.cv.Wait()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s.conns = nil
 | 
				
			||||||
 | 
						if s.events != nil {
 | 
				
			||||||
 | 
							s.events.Finish()
 | 
				
			||||||
 | 
							s.events = nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	internal.TestingCloseConns = func(arg interface{}) {
 | 
						internal.TestingCloseConns = func(arg interface{}) {
 | 
				
			||||||
		arg.(*Server).testingCloseConns()
 | 
							arg.(*Server).testingCloseConns()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										115
									
								
								vendor/google.golang.org/grpc/stream.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										115
									
								
								vendor/google.golang.org/grpc/stream.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -37,6 +37,7 @@ import (
 | 
				
			|||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
 | 
						"math"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,12 +85,9 @@ type ClientStream interface {
 | 
				
			|||||||
	// Header returns the header metadata received from the server if there
 | 
						// Header returns the header metadata received from the server if there
 | 
				
			||||||
	// is any. It blocks if the metadata is not ready to read.
 | 
						// is any. It blocks if the metadata is not ready to read.
 | 
				
			||||||
	Header() (metadata.MD, error)
 | 
						Header() (metadata.MD, error)
 | 
				
			||||||
	// Trailer returns the trailer metadata from the server. It must be called
 | 
						// Trailer returns the trailer metadata from the server, if there is any.
 | 
				
			||||||
	// after stream.Recv() returns non-nil error (including io.EOF) for
 | 
						// It must only be called after stream.CloseAndRecv has returned, or
 | 
				
			||||||
	// bi-directional streaming and server streaming or stream.CloseAndRecv()
 | 
						// stream.Recv has returned a non-nil error (including io.EOF).
 | 
				
			||||||
	// returns for client streaming in order to receive trailer metadata if
 | 
					 | 
				
			||||||
	// present. Otherwise, it could returns an empty MD even though trailer
 | 
					 | 
				
			||||||
	// is present.
 | 
					 | 
				
			||||||
	Trailer() metadata.MD
 | 
						Trailer() metadata.MD
 | 
				
			||||||
	// CloseSend closes the send direction of the stream. It closes the stream
 | 
						// CloseSend closes the send direction of the stream. It closes the stream
 | 
				
			||||||
	// when non-nil error is met.
 | 
						// when non-nil error is met.
 | 
				
			||||||
@@ -99,11 +97,10 @@ type ClientStream interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// NewClientStream creates a new Stream for the client side. This is called
 | 
					// NewClientStream creates a new Stream for the client side. This is called
 | 
				
			||||||
// by generated code.
 | 
					// by generated code.
 | 
				
			||||||
func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) {
 | 
					func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		t   transport.ClientTransport
 | 
							t   transport.ClientTransport
 | 
				
			||||||
		s   *transport.Stream
 | 
							s   *transport.Stream
 | 
				
			||||||
		err error
 | 
					 | 
				
			||||||
		put func()
 | 
							put func()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	c := defaultCallInfo
 | 
						c := defaultCallInfo
 | 
				
			||||||
@@ -120,27 +117,24 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
 | 
				
			|||||||
	if cc.dopts.cp != nil {
 | 
						if cc.dopts.cp != nil {
 | 
				
			||||||
		callHdr.SendCompress = cc.dopts.cp.Type()
 | 
							callHdr.SendCompress = cc.dopts.cp.Type()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cs := &clientStream{
 | 
						var trInfo traceInfo
 | 
				
			||||||
		opts:    opts,
 | 
						if EnableTracing {
 | 
				
			||||||
		c:       c,
 | 
							trInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method)
 | 
				
			||||||
		desc:    desc,
 | 
							trInfo.firstLine.client = true
 | 
				
			||||||
		codec:   cc.dopts.codec,
 | 
					 | 
				
			||||||
		cp:      cc.dopts.cp,
 | 
					 | 
				
			||||||
		dc:      cc.dopts.dc,
 | 
					 | 
				
			||||||
		tracing: EnableTracing,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if cc.dopts.cp != nil {
 | 
					 | 
				
			||||||
		callHdr.SendCompress = cc.dopts.cp.Type()
 | 
					 | 
				
			||||||
		cs.cbuf = new(bytes.Buffer)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if cs.tracing {
 | 
					 | 
				
			||||||
		cs.trInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method)
 | 
					 | 
				
			||||||
		cs.trInfo.firstLine.client = true
 | 
					 | 
				
			||||||
		if deadline, ok := ctx.Deadline(); ok {
 | 
							if deadline, ok := ctx.Deadline(); ok {
 | 
				
			||||||
			cs.trInfo.firstLine.deadline = deadline.Sub(time.Now())
 | 
								trInfo.firstLine.deadline = deadline.Sub(time.Now())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		cs.trInfo.tr.LazyLog(&cs.trInfo.firstLine, false)
 | 
							trInfo.tr.LazyLog(&trInfo.firstLine, false)
 | 
				
			||||||
		ctx = trace.NewContext(ctx, cs.trInfo.tr)
 | 
							ctx = trace.NewContext(ctx, trInfo.tr)
 | 
				
			||||||
 | 
							defer func() {
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									// Need to call tr.finish() if error is returned.
 | 
				
			||||||
 | 
									// Because tr will not be returned to caller.
 | 
				
			||||||
 | 
									trInfo.tr.LazyPrintf("RPC: [%v]", err)
 | 
				
			||||||
 | 
									trInfo.tr.SetError()
 | 
				
			||||||
 | 
									trInfo.tr.Finish()
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	gopts := BalancerGetOptions{
 | 
						gopts := BalancerGetOptions{
 | 
				
			||||||
		BlockingWait: !c.failFast,
 | 
							BlockingWait: !c.failFast,
 | 
				
			||||||
@@ -152,9 +146,9 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
 | 
				
			|||||||
			if _, ok := err.(*rpcError); ok {
 | 
								if _, ok := err.(*rpcError); ok {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err == errConnClosing {
 | 
								if err == errConnClosing || err == errConnUnavailable {
 | 
				
			||||||
				if c.failFast {
 | 
									if c.failFast {
 | 
				
			||||||
					return nil, Errorf(codes.Unavailable, "%v", errConnClosing)
 | 
										return nil, Errorf(codes.Unavailable, "%v", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -168,9 +162,8 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
 | 
				
			|||||||
				put()
 | 
									put()
 | 
				
			||||||
				put = nil
 | 
									put = nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if _, ok := err.(transport.ConnectionError); ok {
 | 
								if _, ok := err.(transport.ConnectionError); ok || err == transport.ErrStreamDrain {
 | 
				
			||||||
				if c.failFast {
 | 
									if c.failFast {
 | 
				
			||||||
					cs.finish(err)
 | 
					 | 
				
			||||||
					return nil, toRPCErr(err)
 | 
										return nil, toRPCErr(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
@@ -179,16 +172,43 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		break
 | 
							break
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cs.put = put
 | 
						cs := &clientStream{
 | 
				
			||||||
	cs.t = t
 | 
							opts:  opts,
 | 
				
			||||||
	cs.s = s
 | 
							c:     c,
 | 
				
			||||||
	cs.p = &parser{r: s}
 | 
							desc:  desc,
 | 
				
			||||||
	// Listen on ctx.Done() to detect cancellation when there is no pending
 | 
							codec: cc.dopts.codec,
 | 
				
			||||||
	// I/O operations on this stream.
 | 
							cp:    cc.dopts.cp,
 | 
				
			||||||
 | 
							dc:    cc.dopts.dc,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							put: put,
 | 
				
			||||||
 | 
							t:   t,
 | 
				
			||||||
 | 
							s:   s,
 | 
				
			||||||
 | 
							p:   &parser{r: s},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tracing: EnableTracing,
 | 
				
			||||||
 | 
							trInfo:  trInfo,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if cc.dopts.cp != nil {
 | 
				
			||||||
 | 
							cs.cbuf = new(bytes.Buffer)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Listen on ctx.Done() to detect cancellation and s.Done() to detect normal termination
 | 
				
			||||||
 | 
						// when there is no pending I/O operations on this stream.
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case <-t.Error():
 | 
							case <-t.Error():
 | 
				
			||||||
			// Incur transport error, simply exit.
 | 
								// Incur transport error, simply exit.
 | 
				
			||||||
 | 
							case <-s.Done():
 | 
				
			||||||
 | 
								// TODO: The trace of the RPC is terminated here when there is no pending
 | 
				
			||||||
 | 
								// I/O, which is probably not the optimal solution.
 | 
				
			||||||
 | 
								if s.StatusCode() == codes.OK {
 | 
				
			||||||
 | 
									cs.finish(nil)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									cs.finish(Errorf(s.StatusCode(), "%s", s.StatusDesc()))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								cs.closeTransportStream(nil)
 | 
				
			||||||
 | 
							case <-s.GoAway():
 | 
				
			||||||
 | 
								cs.finish(errConnDrain)
 | 
				
			||||||
 | 
								cs.closeTransportStream(errConnDrain)
 | 
				
			||||||
		case <-s.Context().Done():
 | 
							case <-s.Context().Done():
 | 
				
			||||||
			err := s.Context().Err()
 | 
								err := s.Context().Err()
 | 
				
			||||||
			cs.finish(err)
 | 
								cs.finish(err)
 | 
				
			||||||
@@ -251,7 +271,17 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) {
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			cs.finish(err)
 | 
								cs.finish(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err == nil || err == io.EOF {
 | 
							if err == nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err == io.EOF {
 | 
				
			||||||
 | 
								// Specialize the process for server streaming. SendMesg is only called
 | 
				
			||||||
 | 
								// once when creating the stream object. io.EOF needs to be skipped when
 | 
				
			||||||
 | 
								// the rpc is early finished (before the stream object is created.).
 | 
				
			||||||
 | 
								// TODO: It is probably better to move this into the generated code.
 | 
				
			||||||
 | 
								if !cs.desc.ClientStreams && cs.desc.ServerStreams {
 | 
				
			||||||
 | 
									err = nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if _, ok := err.(transport.ConnectionError); !ok {
 | 
							if _, ok := err.(transport.ConnectionError); !ok {
 | 
				
			||||||
@@ -272,7 +302,7 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cs *clientStream) RecvMsg(m interface{}) (err error) {
 | 
					func (cs *clientStream) RecvMsg(m interface{}) (err error) {
 | 
				
			||||||
	err = recv(cs.p, cs.codec, cs.s, cs.dc, m)
 | 
						err = recv(cs.p, cs.codec, cs.s, cs.dc, m, math.MaxInt32)
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		// err != nil indicates the termination of the stream.
 | 
							// err != nil indicates the termination of the stream.
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -291,7 +321,7 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) {
 | 
				
			|||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Special handling for client streaming rpc.
 | 
							// Special handling for client streaming rpc.
 | 
				
			||||||
		err = recv(cs.p, cs.codec, cs.s, cs.dc, m)
 | 
							err = recv(cs.p, cs.codec, cs.s, cs.dc, m, math.MaxInt32)
 | 
				
			||||||
		cs.closeTransportStream(err)
 | 
							cs.closeTransportStream(err)
 | 
				
			||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			return toRPCErr(errors.New("grpc: client streaming protocol violation: get <nil>, want <EOF>"))
 | 
								return toRPCErr(errors.New("grpc: client streaming protocol violation: get <nil>, want <EOF>"))
 | 
				
			||||||
@@ -326,7 +356,7 @@ func (cs *clientStream) CloseSend() (err error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	if err == nil || err == io.EOF {
 | 
						if err == nil || err == io.EOF {
 | 
				
			||||||
		return
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, ok := err.(transport.ConnectionError); !ok {
 | 
						if _, ok := err.(transport.ConnectionError); !ok {
 | 
				
			||||||
		cs.closeTransportStream(err)
 | 
							cs.closeTransportStream(err)
 | 
				
			||||||
@@ -392,6 +422,7 @@ type serverStream struct {
 | 
				
			|||||||
	cp         Compressor
 | 
						cp         Compressor
 | 
				
			||||||
	dc         Decompressor
 | 
						dc         Decompressor
 | 
				
			||||||
	cbuf       *bytes.Buffer
 | 
						cbuf       *bytes.Buffer
 | 
				
			||||||
 | 
						maxMsgSize int
 | 
				
			||||||
	statusCode codes.Code
 | 
						statusCode codes.Code
 | 
				
			||||||
	statusDesc string
 | 
						statusDesc string
 | 
				
			||||||
	trInfo     *traceInfo
 | 
						trInfo     *traceInfo
 | 
				
			||||||
@@ -458,5 +489,5 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) {
 | 
				
			|||||||
			ss.mu.Unlock()
 | 
								ss.mu.Unlock()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	return recv(ss.p, ss.codec, ss.s, ss.dc, m)
 | 
						return recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxMsgSize)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								vendor/google.golang.org/grpc/transport/control.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/google.golang.org/grpc/transport/control.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -72,6 +72,11 @@ type resetStream struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (*resetStream) item() {}
 | 
					func (*resetStream) item() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type goAway struct {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (*goAway) item() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type flushIO struct {
 | 
					type flushIO struct {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										46
									
								
								vendor/google.golang.org/grpc/transport/go16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/google.golang.org/grpc/transport/go16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					// +build go1.6,!go1.7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016, Google Inc.
 | 
				
			||||||
 | 
					 * All rights reserved.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					 * modification, are permitted provided that the following conditions are
 | 
				
			||||||
 | 
					 * met:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					 * notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					 *     * Redistributions in binary form must reproduce the above
 | 
				
			||||||
 | 
					 * copyright notice, this list of conditions and the following disclaimer
 | 
				
			||||||
 | 
					 * in the documentation and/or other materials provided with the
 | 
				
			||||||
 | 
					 * distribution.
 | 
				
			||||||
 | 
					 *     * Neither the name of Google Inc. nor the names of its
 | 
				
			||||||
 | 
					 * contributors may be used to endorse or promote products derived from
 | 
				
			||||||
 | 
					 * this software without specific prior written permission.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
				
			||||||
 | 
					 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
				
			||||||
 | 
					 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
				
			||||||
 | 
					 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
				
			||||||
 | 
					 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
				
			||||||
 | 
					 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
 | 
					 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
				
			||||||
 | 
					 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package transport
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"golang.org/x/net/context"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dialContext connects to the address on the named network.
 | 
				
			||||||
 | 
					func dialContext(ctx context.Context, network, address string) (net.Conn, error) {
 | 
				
			||||||
 | 
						return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										46
									
								
								vendor/google.golang.org/grpc/transport/go17.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/google.golang.org/grpc/transport/go17.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					// +build go1.7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016, Google Inc.
 | 
				
			||||||
 | 
					 * All rights reserved.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					 * modification, are permitted provided that the following conditions are
 | 
				
			||||||
 | 
					 * met:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					 * notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					 *     * Redistributions in binary form must reproduce the above
 | 
				
			||||||
 | 
					 * copyright notice, this list of conditions and the following disclaimer
 | 
				
			||||||
 | 
					 * in the documentation and/or other materials provided with the
 | 
				
			||||||
 | 
					 * distribution.
 | 
				
			||||||
 | 
					 *     * Neither the name of Google Inc. nor the names of its
 | 
				
			||||||
 | 
					 * contributors may be used to endorse or promote products derived from
 | 
				
			||||||
 | 
					 * this software without specific prior written permission.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
				
			||||||
 | 
					 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
				
			||||||
 | 
					 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
				
			||||||
 | 
					 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
				
			||||||
 | 
					 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
				
			||||||
 | 
					 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
 | 
					 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
				
			||||||
 | 
					 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package transport
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"golang.org/x/net/context"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dialContext connects to the address on the named network.
 | 
				
			||||||
 | 
					func dialContext(ctx context.Context, network, address string) (net.Conn, error) {
 | 
				
			||||||
 | 
						return (&net.Dialer{}).DialContext(ctx, network, address)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								vendor/google.golang.org/grpc/transport/handler_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/google.golang.org/grpc/transport/handler_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -83,7 +83,7 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request) (ServerTr
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if v := r.Header.Get("grpc-timeout"); v != "" {
 | 
						if v := r.Header.Get("grpc-timeout"); v != "" {
 | 
				
			||||||
		to, err := timeoutDecode(v)
 | 
							to, err := decodeTimeout(v)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, StreamErrorf(codes.Internal, "malformed time-out: %v", err)
 | 
								return nil, StreamErrorf(codes.Internal, "malformed time-out: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -194,7 +194,7 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, statusCode codes.Code,
 | 
				
			|||||||
		h := ht.rw.Header()
 | 
							h := ht.rw.Header()
 | 
				
			||||||
		h.Set("Grpc-Status", fmt.Sprintf("%d", statusCode))
 | 
							h.Set("Grpc-Status", fmt.Sprintf("%d", statusCode))
 | 
				
			||||||
		if statusDesc != "" {
 | 
							if statusDesc != "" {
 | 
				
			||||||
			h.Set("Grpc-Message", statusDesc)
 | 
								h.Set("Grpc-Message", encodeGrpcMessage(statusDesc))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if md := s.Trailer(); len(md) > 0 {
 | 
							if md := s.Trailer(); len(md) > 0 {
 | 
				
			||||||
			for k, vv := range md {
 | 
								for k, vv := range md {
 | 
				
			||||||
@@ -370,6 +370,10 @@ func (ht *serverHandlerTransport) runStream() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ht *serverHandlerTransport) Drain() {
 | 
				
			||||||
 | 
						panic("Drain() is not implemented")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// mapRecvMsgError returns the non-nil err into the appropriate
 | 
					// mapRecvMsgError returns the non-nil err into the appropriate
 | 
				
			||||||
// error value as expected by callers of *grpc.parser.recvMsg.
 | 
					// error value as expected by callers of *grpc.parser.recvMsg.
 | 
				
			||||||
// In particular, in can only be:
 | 
					// In particular, in can only be:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										202
									
								
								vendor/google.golang.org/grpc/transport/http2_client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/google.golang.org/grpc/transport/http2_client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -35,6 +35,7 @@ package transport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"math"
 | 
						"math"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
@@ -71,6 +72,9 @@ type http2Client struct {
 | 
				
			|||||||
	shutdownChan chan struct{}
 | 
						shutdownChan chan struct{}
 | 
				
			||||||
	// errorChan is closed to notify the I/O error to the caller.
 | 
						// errorChan is closed to notify the I/O error to the caller.
 | 
				
			||||||
	errorChan chan struct{}
 | 
						errorChan chan struct{}
 | 
				
			||||||
 | 
						// goAway is closed to notify the upper layer (i.e., addrConn.transportMonitor)
 | 
				
			||||||
 | 
						// that the server sent GoAway on this transport.
 | 
				
			||||||
 | 
						goAway chan struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	framer *framer
 | 
						framer *framer
 | 
				
			||||||
	hBuf   *bytes.Buffer  // the buffer for HPACK encoding
 | 
						hBuf   *bytes.Buffer  // the buffer for HPACK encoding
 | 
				
			||||||
@@ -97,41 +101,44 @@ type http2Client struct {
 | 
				
			|||||||
	maxStreams int
 | 
						maxStreams int
 | 
				
			||||||
	// the per-stream outbound flow control window size set by the peer.
 | 
						// the per-stream outbound flow control window size set by the peer.
 | 
				
			||||||
	streamSendQuota uint32
 | 
						streamSendQuota uint32
 | 
				
			||||||
 | 
						// goAwayID records the Last-Stream-ID in the GoAway frame from the server.
 | 
				
			||||||
 | 
						goAwayID uint32
 | 
				
			||||||
 | 
						// prevGoAway ID records the Last-Stream-ID in the previous GOAway frame.
 | 
				
			||||||
 | 
						prevGoAwayID uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func dial(fn func(context.Context, string) (net.Conn, error), ctx context.Context, addr string) (net.Conn, error) {
 | 
				
			||||||
 | 
						if fn != nil {
 | 
				
			||||||
 | 
							return fn(ctx, addr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return dialContext(ctx, "tcp", addr)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2
 | 
					// newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2
 | 
				
			||||||
// and starts to receive messages on it. Non-nil error returns if construction
 | 
					// and starts to receive messages on it. Non-nil error returns if construction
 | 
				
			||||||
// fails.
 | 
					// fails.
 | 
				
			||||||
func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err error) {
 | 
					func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ ClientTransport, err error) {
 | 
				
			||||||
	if opts.Dialer == nil {
 | 
					 | 
				
			||||||
		// Set the default Dialer.
 | 
					 | 
				
			||||||
		opts.Dialer = func(addr string, timeout time.Duration) (net.Conn, error) {
 | 
					 | 
				
			||||||
			return net.DialTimeout("tcp", addr, timeout)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	scheme := "http"
 | 
						scheme := "http"
 | 
				
			||||||
	startT := time.Now()
 | 
						conn, connErr := dial(opts.Dialer, ctx, addr)
 | 
				
			||||||
	timeout := opts.Timeout
 | 
					 | 
				
			||||||
	conn, connErr := opts.Dialer(addr, timeout)
 | 
					 | 
				
			||||||
	if connErr != nil {
 | 
						if connErr != nil {
 | 
				
			||||||
		return nil, ConnectionErrorf("transport: %v", connErr)
 | 
							return nil, ConnectionErrorf(true, connErr, "transport: %v", connErr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var authInfo credentials.AuthInfo
 | 
						// Any further errors will close the underlying connection
 | 
				
			||||||
	if opts.TransportCredentials != nil {
 | 
						defer func(conn net.Conn) {
 | 
				
			||||||
		scheme = "https"
 | 
					 | 
				
			||||||
		if timeout > 0 {
 | 
					 | 
				
			||||||
			timeout -= time.Since(startT)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		conn, authInfo, connErr = opts.TransportCredentials.ClientHandshake(addr, conn, timeout)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if connErr != nil {
 | 
					 | 
				
			||||||
		return nil, ConnectionErrorf("transport: %v", connErr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			conn.Close()
 | 
								conn.Close()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}(conn)
 | 
				
			||||||
 | 
						var authInfo credentials.AuthInfo
 | 
				
			||||||
 | 
						if creds := opts.TransportCredentials; creds != nil {
 | 
				
			||||||
 | 
							scheme = "https"
 | 
				
			||||||
 | 
							conn, authInfo, connErr = creds.ClientHandshake(ctx, addr, conn)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if connErr != nil {
 | 
				
			||||||
 | 
							// Credentials handshake error is not a temporary error (unless the error
 | 
				
			||||||
 | 
							// was the connection closing).
 | 
				
			||||||
 | 
							return nil, ConnectionErrorf(connErr == io.EOF, connErr, "transport: %v", connErr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	ua := primaryUA
 | 
						ua := primaryUA
 | 
				
			||||||
	if opts.UserAgent != "" {
 | 
						if opts.UserAgent != "" {
 | 
				
			||||||
		ua = opts.UserAgent + " " + ua
 | 
							ua = opts.UserAgent + " " + ua
 | 
				
			||||||
@@ -147,6 +154,7 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e
 | 
				
			|||||||
		writableChan:    make(chan int, 1),
 | 
							writableChan:    make(chan int, 1),
 | 
				
			||||||
		shutdownChan:    make(chan struct{}),
 | 
							shutdownChan:    make(chan struct{}),
 | 
				
			||||||
		errorChan:       make(chan struct{}),
 | 
							errorChan:       make(chan struct{}),
 | 
				
			||||||
 | 
							goAway:          make(chan struct{}),
 | 
				
			||||||
		framer:          newFramer(conn),
 | 
							framer:          newFramer(conn),
 | 
				
			||||||
		hBuf:            &buf,
 | 
							hBuf:            &buf,
 | 
				
			||||||
		hEnc:            hpack.NewEncoder(&buf),
 | 
							hEnc:            hpack.NewEncoder(&buf),
 | 
				
			||||||
@@ -168,11 +176,11 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e
 | 
				
			|||||||
	n, err := t.conn.Write(clientPreface)
 | 
						n, err := t.conn.Write(clientPreface)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Close()
 | 
							t.Close()
 | 
				
			||||||
		return nil, ConnectionErrorf("transport: %v", err)
 | 
							return nil, ConnectionErrorf(true, err, "transport: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if n != len(clientPreface) {
 | 
						if n != len(clientPreface) {
 | 
				
			||||||
		t.Close()
 | 
							t.Close()
 | 
				
			||||||
		return nil, ConnectionErrorf("transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface))
 | 
							return nil, ConnectionErrorf(true, err, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if initialWindowSize != defaultWindowSize {
 | 
						if initialWindowSize != defaultWindowSize {
 | 
				
			||||||
		err = t.framer.writeSettings(true, http2.Setting{
 | 
							err = t.framer.writeSettings(true, http2.Setting{
 | 
				
			||||||
@@ -184,13 +192,13 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Close()
 | 
							t.Close()
 | 
				
			||||||
		return nil, ConnectionErrorf("transport: %v", err)
 | 
							return nil, ConnectionErrorf(true, err, "transport: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Adjust the connection flow control window if needed.
 | 
						// Adjust the connection flow control window if needed.
 | 
				
			||||||
	if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 {
 | 
						if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 {
 | 
				
			||||||
		if err := t.framer.writeWindowUpdate(true, 0, delta); err != nil {
 | 
							if err := t.framer.writeWindowUpdate(true, 0, delta); err != nil {
 | 
				
			||||||
			t.Close()
 | 
								t.Close()
 | 
				
			||||||
			return nil, ConnectionErrorf("transport: %v", err)
 | 
								return nil, ConnectionErrorf(true, err, "transport: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	go t.controller()
 | 
						go t.controller()
 | 
				
			||||||
@@ -202,6 +210,8 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream {
 | 
				
			|||||||
	// TODO(zhaoq): Handle uint32 overflow of Stream.id.
 | 
						// TODO(zhaoq): Handle uint32 overflow of Stream.id.
 | 
				
			||||||
	s := &Stream{
 | 
						s := &Stream{
 | 
				
			||||||
		id:            t.nextID,
 | 
							id:            t.nextID,
 | 
				
			||||||
 | 
							done:          make(chan struct{}),
 | 
				
			||||||
 | 
							goAway:        make(chan struct{}),
 | 
				
			||||||
		method:        callHdr.Method,
 | 
							method:        callHdr.Method,
 | 
				
			||||||
		sendCompress:  callHdr.SendCompress,
 | 
							sendCompress:  callHdr.SendCompress,
 | 
				
			||||||
		buf:           newRecvBuffer(),
 | 
							buf:           newRecvBuffer(),
 | 
				
			||||||
@@ -217,6 +227,7 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream {
 | 
				
			|||||||
	s.ctx, s.cancel = context.WithCancel(ctx)
 | 
						s.ctx, s.cancel = context.WithCancel(ctx)
 | 
				
			||||||
	s.dec = &recvBufferReader{
 | 
						s.dec = &recvBufferReader{
 | 
				
			||||||
		ctx:    s.ctx,
 | 
							ctx:    s.ctx,
 | 
				
			||||||
 | 
							goAway: s.goAway,
 | 
				
			||||||
		recv:   s.buf,
 | 
							recv:   s.buf,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return s
 | 
						return s
 | 
				
			||||||
@@ -271,6 +282,10 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
 | 
				
			|||||||
		t.mu.Unlock()
 | 
							t.mu.Unlock()
 | 
				
			||||||
		return nil, ErrConnClosing
 | 
							return nil, ErrConnClosing
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if t.state == draining {
 | 
				
			||||||
 | 
							t.mu.Unlock()
 | 
				
			||||||
 | 
							return nil, ErrStreamDrain
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if t.state != reachable {
 | 
						if t.state != reachable {
 | 
				
			||||||
		t.mu.Unlock()
 | 
							t.mu.Unlock()
 | 
				
			||||||
		return nil, ErrConnClosing
 | 
							return nil, ErrConnClosing
 | 
				
			||||||
@@ -278,7 +293,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
 | 
				
			|||||||
	checkStreamsQuota := t.streamsQuota != nil
 | 
						checkStreamsQuota := t.streamsQuota != nil
 | 
				
			||||||
	t.mu.Unlock()
 | 
						t.mu.Unlock()
 | 
				
			||||||
	if checkStreamsQuota {
 | 
						if checkStreamsQuota {
 | 
				
			||||||
		sq, err := wait(ctx, t.shutdownChan, t.streamsQuota.acquire())
 | 
							sq, err := wait(ctx, nil, nil, t.shutdownChan, t.streamsQuota.acquire())
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -287,7 +302,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
 | 
				
			|||||||
			t.streamsQuota.add(sq - 1)
 | 
								t.streamsQuota.add(sq - 1)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, err := wait(ctx, t.shutdownChan, t.writableChan); err != nil {
 | 
						if _, err := wait(ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil {
 | 
				
			||||||
		// Return the quota back now because there is no stream returned to the caller.
 | 
							// Return the quota back now because there is no stream returned to the caller.
 | 
				
			||||||
		if _, ok := err.(StreamError); ok && checkStreamsQuota {
 | 
							if _, ok := err.(StreamError); ok && checkStreamsQuota {
 | 
				
			||||||
			t.streamsQuota.add(1)
 | 
								t.streamsQuota.add(1)
 | 
				
			||||||
@@ -295,6 +310,15 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	t.mu.Lock()
 | 
						t.mu.Lock()
 | 
				
			||||||
 | 
						if t.state == draining {
 | 
				
			||||||
 | 
							t.mu.Unlock()
 | 
				
			||||||
 | 
							if checkStreamsQuota {
 | 
				
			||||||
 | 
								t.streamsQuota.add(1)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Need to make t writable again so that the rpc in flight can still proceed.
 | 
				
			||||||
 | 
							t.writableChan <- 0
 | 
				
			||||||
 | 
							return nil, ErrStreamDrain
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if t.state != reachable {
 | 
						if t.state != reachable {
 | 
				
			||||||
		t.mu.Unlock()
 | 
							t.mu.Unlock()
 | 
				
			||||||
		return nil, ErrConnClosing
 | 
							return nil, ErrConnClosing
 | 
				
			||||||
@@ -329,7 +353,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
 | 
				
			|||||||
		t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: callHdr.SendCompress})
 | 
							t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: callHdr.SendCompress})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if timeout > 0 {
 | 
						if timeout > 0 {
 | 
				
			||||||
		t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: timeoutEncode(timeout)})
 | 
							t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: encodeTimeout(timeout)})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for k, v := range authData {
 | 
						for k, v := range authData {
 | 
				
			||||||
		// Capital header names are illegal in HTTP/2.
 | 
							// Capital header names are illegal in HTTP/2.
 | 
				
			||||||
@@ -384,7 +408,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			t.notifyError(err)
 | 
								t.notifyError(err)
 | 
				
			||||||
			return nil, ConnectionErrorf("transport: %v", err)
 | 
								return nil, ConnectionErrorf(true, err, "transport: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	t.writableChan <- 0
 | 
						t.writableChan <- 0
 | 
				
			||||||
@@ -403,22 +427,17 @@ func (t *http2Client) CloseStream(s *Stream, err error) {
 | 
				
			|||||||
	if t.streamsQuota != nil {
 | 
						if t.streamsQuota != nil {
 | 
				
			||||||
		updateStreams = true
 | 
							updateStreams = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if t.state == draining && len(t.activeStreams) == 1 {
 | 
						delete(t.activeStreams, s.id)
 | 
				
			||||||
 | 
						if t.state == draining && len(t.activeStreams) == 0 {
 | 
				
			||||||
		// The transport is draining and s is the last live stream on t.
 | 
							// The transport is draining and s is the last live stream on t.
 | 
				
			||||||
		t.mu.Unlock()
 | 
							t.mu.Unlock()
 | 
				
			||||||
		t.Close()
 | 
							t.Close()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	delete(t.activeStreams, s.id)
 | 
					 | 
				
			||||||
	t.mu.Unlock()
 | 
						t.mu.Unlock()
 | 
				
			||||||
	if updateStreams {
 | 
						if updateStreams {
 | 
				
			||||||
		t.streamsQuota.add(1)
 | 
							t.streamsQuota.add(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// In case stream sending and receiving are invoked in separate
 | 
					 | 
				
			||||||
	// goroutines (e.g., bi-directional streaming), the caller needs
 | 
					 | 
				
			||||||
	// to call cancel on the stream to interrupt the blocking on
 | 
					 | 
				
			||||||
	// other goroutines.
 | 
					 | 
				
			||||||
	s.cancel()
 | 
					 | 
				
			||||||
	s.mu.Lock()
 | 
						s.mu.Lock()
 | 
				
			||||||
	if q := s.fc.resetPendingData(); q > 0 {
 | 
						if q := s.fc.resetPendingData(); q > 0 {
 | 
				
			||||||
		if n := t.fc.onRead(q); n > 0 {
 | 
							if n := t.fc.onRead(q); n > 0 {
 | 
				
			||||||
@@ -445,13 +464,13 @@ func (t *http2Client) CloseStream(s *Stream, err error) {
 | 
				
			|||||||
// accessed any more.
 | 
					// accessed any more.
 | 
				
			||||||
func (t *http2Client) Close() (err error) {
 | 
					func (t *http2Client) Close() (err error) {
 | 
				
			||||||
	t.mu.Lock()
 | 
						t.mu.Lock()
 | 
				
			||||||
	if t.state == reachable {
 | 
					 | 
				
			||||||
		close(t.errorChan)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if t.state == closing {
 | 
						if t.state == closing {
 | 
				
			||||||
		t.mu.Unlock()
 | 
							t.mu.Unlock()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if t.state == reachable || t.state == draining {
 | 
				
			||||||
 | 
							close(t.errorChan)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	t.state = closing
 | 
						t.state = closing
 | 
				
			||||||
	t.mu.Unlock()
 | 
						t.mu.Unlock()
 | 
				
			||||||
	close(t.shutdownChan)
 | 
						close(t.shutdownChan)
 | 
				
			||||||
@@ -475,10 +494,35 @@ func (t *http2Client) Close() (err error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (t *http2Client) GracefulClose() error {
 | 
					func (t *http2Client) GracefulClose() error {
 | 
				
			||||||
	t.mu.Lock()
 | 
						t.mu.Lock()
 | 
				
			||||||
	if t.state == closing {
 | 
						switch t.state {
 | 
				
			||||||
 | 
						case unreachable:
 | 
				
			||||||
 | 
							// The server may close the connection concurrently. t is not available for
 | 
				
			||||||
 | 
							// any streams. Close it now.
 | 
				
			||||||
 | 
							t.mu.Unlock()
 | 
				
			||||||
 | 
							t.Close()
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						case closing:
 | 
				
			||||||
		t.mu.Unlock()
 | 
							t.mu.Unlock()
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// Notify the streams which were initiated after the server sent GOAWAY.
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
						case <-t.goAway:
 | 
				
			||||||
 | 
							n := t.prevGoAwayID
 | 
				
			||||||
 | 
							if n == 0 && t.nextID > 1 {
 | 
				
			||||||
 | 
								n = t.nextID - 2
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							m := t.goAwayID + 2
 | 
				
			||||||
 | 
							if m == 2 {
 | 
				
			||||||
 | 
								m = 1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for i := m; i <= n; i += 2 {
 | 
				
			||||||
 | 
								if s, ok := t.activeStreams[i]; ok {
 | 
				
			||||||
 | 
									close(s.goAway)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if t.state == draining {
 | 
						if t.state == draining {
 | 
				
			||||||
		t.mu.Unlock()
 | 
							t.mu.Unlock()
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
@@ -504,15 +548,15 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
 | 
				
			|||||||
			size := http2MaxFrameLen
 | 
								size := http2MaxFrameLen
 | 
				
			||||||
			s.sendQuotaPool.add(0)
 | 
								s.sendQuotaPool.add(0)
 | 
				
			||||||
			// Wait until the stream has some quota to send the data.
 | 
								// Wait until the stream has some quota to send the data.
 | 
				
			||||||
			sq, err := wait(s.ctx, t.shutdownChan, s.sendQuotaPool.acquire())
 | 
								sq, err := wait(s.ctx, s.done, s.goAway, t.shutdownChan, s.sendQuotaPool.acquire())
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			t.sendQuotaPool.add(0)
 | 
								t.sendQuotaPool.add(0)
 | 
				
			||||||
			// Wait until the transport has some quota to send the data.
 | 
								// Wait until the transport has some quota to send the data.
 | 
				
			||||||
			tq, err := wait(s.ctx, t.shutdownChan, t.sendQuotaPool.acquire())
 | 
								tq, err := wait(s.ctx, s.done, s.goAway, t.shutdownChan, t.sendQuotaPool.acquire())
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				if _, ok := err.(StreamError); ok {
 | 
									if _, ok := err.(StreamError); ok || err == io.EOF {
 | 
				
			||||||
					t.sendQuotaPool.cancel()
 | 
										t.sendQuotaPool.cancel()
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
@@ -544,8 +588,8 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
 | 
				
			|||||||
		// Indicate there is a writer who is about to write a data frame.
 | 
							// Indicate there is a writer who is about to write a data frame.
 | 
				
			||||||
		t.framer.adjustNumWriters(1)
 | 
							t.framer.adjustNumWriters(1)
 | 
				
			||||||
		// Got some quota. Try to acquire writing privilege on the transport.
 | 
							// Got some quota. Try to acquire writing privilege on the transport.
 | 
				
			||||||
		if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
 | 
							if _, err := wait(s.ctx, s.done, s.goAway, t.shutdownChan, t.writableChan); err != nil {
 | 
				
			||||||
			if _, ok := err.(StreamError); ok {
 | 
								if _, ok := err.(StreamError); ok || err == io.EOF {
 | 
				
			||||||
				// Return the connection quota back.
 | 
									// Return the connection quota back.
 | 
				
			||||||
				t.sendQuotaPool.add(len(p))
 | 
									t.sendQuotaPool.add(len(p))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -578,7 +622,7 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
 | 
				
			|||||||
		// invoked.
 | 
							// invoked.
 | 
				
			||||||
		if err := t.framer.writeData(forceFlush, s.id, endStream, p); err != nil {
 | 
							if err := t.framer.writeData(forceFlush, s.id, endStream, p); err != nil {
 | 
				
			||||||
			t.notifyError(err)
 | 
								t.notifyError(err)
 | 
				
			||||||
			return ConnectionErrorf("transport: %v", err)
 | 
								return ConnectionErrorf(true, err, "transport: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if t.framer.adjustNumWriters(-1) == 0 {
 | 
							if t.framer.adjustNumWriters(-1) == 0 {
 | 
				
			||||||
			t.framer.flushWrite()
 | 
								t.framer.flushWrite()
 | 
				
			||||||
@@ -593,12 +637,8 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	s.mu.Lock()
 | 
						s.mu.Lock()
 | 
				
			||||||
	if s.state != streamDone {
 | 
						if s.state != streamDone {
 | 
				
			||||||
		if s.state == streamReadDone {
 | 
					 | 
				
			||||||
			s.state = streamDone
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
		s.state = streamWriteDone
 | 
							s.state = streamWriteDone
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.mu.Unlock()
 | 
						s.mu.Unlock()
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -630,7 +670,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) {
 | 
				
			|||||||
func (t *http2Client) handleData(f *http2.DataFrame) {
 | 
					func (t *http2Client) handleData(f *http2.DataFrame) {
 | 
				
			||||||
	size := len(f.Data())
 | 
						size := len(f.Data())
 | 
				
			||||||
	if err := t.fc.onData(uint32(size)); err != nil {
 | 
						if err := t.fc.onData(uint32(size)); err != nil {
 | 
				
			||||||
		t.notifyError(ConnectionErrorf("%v", err))
 | 
							t.notifyError(ConnectionErrorf(true, err, "%v", err))
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Select the right stream to dispatch.
 | 
						// Select the right stream to dispatch.
 | 
				
			||||||
@@ -655,6 +695,7 @@ func (t *http2Client) handleData(f *http2.DataFrame) {
 | 
				
			|||||||
			s.state = streamDone
 | 
								s.state = streamDone
 | 
				
			||||||
			s.statusCode = codes.Internal
 | 
								s.statusCode = codes.Internal
 | 
				
			||||||
			s.statusDesc = err.Error()
 | 
								s.statusDesc = err.Error()
 | 
				
			||||||
 | 
								close(s.done)
 | 
				
			||||||
			s.mu.Unlock()
 | 
								s.mu.Unlock()
 | 
				
			||||||
			s.write(recvMsg{err: io.EOF})
 | 
								s.write(recvMsg{err: io.EOF})
 | 
				
			||||||
			t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl})
 | 
								t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl})
 | 
				
			||||||
@@ -672,13 +713,14 @@ func (t *http2Client) handleData(f *http2.DataFrame) {
 | 
				
			|||||||
	// the read direction is closed, and set the status appropriately.
 | 
						// the read direction is closed, and set the status appropriately.
 | 
				
			||||||
	if f.FrameHeader.Flags.Has(http2.FlagDataEndStream) {
 | 
						if f.FrameHeader.Flags.Has(http2.FlagDataEndStream) {
 | 
				
			||||||
		s.mu.Lock()
 | 
							s.mu.Lock()
 | 
				
			||||||
		if s.state == streamWriteDone {
 | 
							if s.state == streamDone {
 | 
				
			||||||
			s.state = streamDone
 | 
								s.mu.Unlock()
 | 
				
			||||||
		} else {
 | 
								return
 | 
				
			||||||
			s.state = streamReadDone
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							s.state = streamDone
 | 
				
			||||||
		s.statusCode = codes.Internal
 | 
							s.statusCode = codes.Internal
 | 
				
			||||||
		s.statusDesc = "server closed the stream without sending trailers"
 | 
							s.statusDesc = "server closed the stream without sending trailers"
 | 
				
			||||||
 | 
							close(s.done)
 | 
				
			||||||
		s.mu.Unlock()
 | 
							s.mu.Unlock()
 | 
				
			||||||
		s.write(recvMsg{err: io.EOF})
 | 
							s.write(recvMsg{err: io.EOF})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -704,6 +746,8 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) {
 | 
				
			|||||||
		grpclog.Println("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error ", f.ErrCode)
 | 
							grpclog.Println("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error ", f.ErrCode)
 | 
				
			||||||
		s.statusCode = codes.Unknown
 | 
							s.statusCode = codes.Unknown
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						s.statusDesc = fmt.Sprintf("stream terminated by RST_STREAM with error code: %d", f.ErrCode)
 | 
				
			||||||
 | 
						close(s.done)
 | 
				
			||||||
	s.mu.Unlock()
 | 
						s.mu.Unlock()
 | 
				
			||||||
	s.write(recvMsg{err: io.EOF})
 | 
						s.write(recvMsg{err: io.EOF})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -728,7 +772,32 @@ func (t *http2Client) handlePing(f *http2.PingFrame) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
 | 
					func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
 | 
				
			||||||
	// TODO(zhaoq): GoAwayFrame handler to be implemented
 | 
						t.mu.Lock()
 | 
				
			||||||
 | 
						if t.state == reachable || t.state == draining {
 | 
				
			||||||
 | 
							if f.LastStreamID > 0 && f.LastStreamID%2 != 1 {
 | 
				
			||||||
 | 
								t.mu.Unlock()
 | 
				
			||||||
 | 
								t.notifyError(ConnectionErrorf(true, nil, "received illegal http2 GOAWAY frame: stream ID %d is even", f.LastStreamID))
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							select {
 | 
				
			||||||
 | 
							case <-t.goAway:
 | 
				
			||||||
 | 
								id := t.goAwayID
 | 
				
			||||||
 | 
								// t.goAway has been closed (i.e.,multiple GoAways).
 | 
				
			||||||
 | 
								if id < f.LastStreamID {
 | 
				
			||||||
 | 
									t.mu.Unlock()
 | 
				
			||||||
 | 
									t.notifyError(ConnectionErrorf(true, nil, "received illegal http2 GOAWAY frame: previously recv GOAWAY frame with LastStramID %d, currently recv %d", id, f.LastStreamID))
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								t.prevGoAwayID = id
 | 
				
			||||||
 | 
								t.goAwayID = f.LastStreamID
 | 
				
			||||||
 | 
								t.mu.Unlock()
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.goAwayID = f.LastStreamID
 | 
				
			||||||
 | 
							close(t.goAway)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.mu.Unlock()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (t *http2Client) handleWindowUpdate(f *http2.WindowUpdateFrame) {
 | 
					func (t *http2Client) handleWindowUpdate(f *http2.WindowUpdateFrame) {
 | 
				
			||||||
@@ -780,11 +849,11 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
 | 
				
			|||||||
	if len(state.mdata) > 0 {
 | 
						if len(state.mdata) > 0 {
 | 
				
			||||||
		s.trailer = state.mdata
 | 
							s.trailer = state.mdata
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s.state = streamDone
 | 
					 | 
				
			||||||
	s.statusCode = state.statusCode
 | 
						s.statusCode = state.statusCode
 | 
				
			||||||
	s.statusDesc = state.statusDesc
 | 
						s.statusDesc = state.statusDesc
 | 
				
			||||||
 | 
						close(s.done)
 | 
				
			||||||
 | 
						s.state = streamDone
 | 
				
			||||||
	s.mu.Unlock()
 | 
						s.mu.Unlock()
 | 
				
			||||||
 | 
					 | 
				
			||||||
	s.write(recvMsg{err: io.EOF})
 | 
						s.write(recvMsg{err: io.EOF})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -937,13 +1006,22 @@ func (t *http2Client) Error() <-chan struct{} {
 | 
				
			|||||||
	return t.errorChan
 | 
						return t.errorChan
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (t *http2Client) GoAway() <-chan struct{} {
 | 
				
			||||||
 | 
						return t.goAway
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (t *http2Client) notifyError(err error) {
 | 
					func (t *http2Client) notifyError(err error) {
 | 
				
			||||||
	t.mu.Lock()
 | 
						t.mu.Lock()
 | 
				
			||||||
	defer t.mu.Unlock()
 | 
					 | 
				
			||||||
	// make sure t.errorChan is closed only once.
 | 
						// make sure t.errorChan is closed only once.
 | 
				
			||||||
 | 
						if t.state == draining {
 | 
				
			||||||
 | 
							t.mu.Unlock()
 | 
				
			||||||
 | 
							t.Close()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if t.state == reachable {
 | 
						if t.state == reachable {
 | 
				
			||||||
		t.state = unreachable
 | 
							t.state = unreachable
 | 
				
			||||||
		close(t.errorChan)
 | 
							close(t.errorChan)
 | 
				
			||||||
		grpclog.Printf("transport: http2Client.notifyError got notified that the client transport was broken %v.", err)
 | 
							grpclog.Printf("transport: http2Client.notifyError got notified that the client transport was broken %v.", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						t.mu.Unlock()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										74
									
								
								vendor/google.golang.org/grpc/transport/http2_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										74
									
								
								vendor/google.golang.org/grpc/transport/http2_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -111,12 +111,12 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI
 | 
				
			|||||||
			Val: uint32(initialWindowSize)})
 | 
								Val: uint32(initialWindowSize)})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := framer.writeSettings(true, settings...); err != nil {
 | 
						if err := framer.writeSettings(true, settings...); err != nil {
 | 
				
			||||||
		return nil, ConnectionErrorf("transport: %v", err)
 | 
							return nil, ConnectionErrorf(true, err, "transport: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Adjust the connection flow control window if needed.
 | 
						// Adjust the connection flow control window if needed.
 | 
				
			||||||
	if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 {
 | 
						if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 {
 | 
				
			||||||
		if err := framer.writeWindowUpdate(true, 0, delta); err != nil {
 | 
							if err := framer.writeWindowUpdate(true, 0, delta); err != nil {
 | 
				
			||||||
			return nil, ConnectionErrorf("transport: %v", err)
 | 
								return nil, ConnectionErrorf(true, err, "transport: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var buf bytes.Buffer
 | 
						var buf bytes.Buffer
 | 
				
			||||||
@@ -142,7 +142,7 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// operateHeader takes action on the decoded headers.
 | 
					// operateHeader takes action on the decoded headers.
 | 
				
			||||||
func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream)) {
 | 
					func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream)) (close bool) {
 | 
				
			||||||
	buf := newRecvBuffer()
 | 
						buf := newRecvBuffer()
 | 
				
			||||||
	s := &Stream{
 | 
						s := &Stream{
 | 
				
			||||||
		id:  frame.Header().StreamID,
 | 
							id:  frame.Header().StreamID,
 | 
				
			||||||
@@ -205,6 +205,13 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
 | 
				
			|||||||
		t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream})
 | 
							t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if s.id%2 != 1 || s.id <= t.maxStreamID {
 | 
				
			||||||
 | 
							t.mu.Unlock()
 | 
				
			||||||
 | 
							// illegal gRPC stream id.
 | 
				
			||||||
 | 
							grpclog.Println("transport: http2Server.HandleStreams received an illegal stream id: ", s.id)
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.maxStreamID = s.id
 | 
				
			||||||
	s.sendQuotaPool = newQuotaPool(int(t.streamSendQuota))
 | 
						s.sendQuotaPool = newQuotaPool(int(t.streamSendQuota))
 | 
				
			||||||
	t.activeStreams[s.id] = s
 | 
						t.activeStreams[s.id] = s
 | 
				
			||||||
	t.mu.Unlock()
 | 
						t.mu.Unlock()
 | 
				
			||||||
@@ -212,6 +219,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
 | 
				
			|||||||
		t.updateWindow(s, uint32(n))
 | 
							t.updateWindow(s, uint32(n))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	handle(s)
 | 
						handle(s)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HandleStreams receives incoming streams using the given handler. This is
 | 
					// HandleStreams receives incoming streams using the given handler. This is
 | 
				
			||||||
@@ -231,6 +239,10 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	frame, err := t.framer.readFrame()
 | 
						frame, err := t.framer.readFrame()
 | 
				
			||||||
 | 
						if err == io.EOF || err == io.ErrUnexpectedEOF {
 | 
				
			||||||
 | 
							t.Close()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		grpclog.Printf("transport: http2Server.HandleStreams failed to read frame: %v", err)
 | 
							grpclog.Printf("transport: http2Server.HandleStreams failed to read frame: %v", err)
 | 
				
			||||||
		t.Close()
 | 
							t.Close()
 | 
				
			||||||
@@ -257,20 +269,20 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) {
 | 
				
			|||||||
				t.controlBuf.put(&resetStream{se.StreamID, se.Code})
 | 
									t.controlBuf.put(&resetStream{se.StreamID, se.Code})
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if err == io.EOF || err == io.ErrUnexpectedEOF {
 | 
				
			||||||
 | 
									t.Close()
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								grpclog.Printf("transport: http2Server.HandleStreams failed to read frame: %v", err)
 | 
				
			||||||
			t.Close()
 | 
								t.Close()
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		switch frame := frame.(type) {
 | 
							switch frame := frame.(type) {
 | 
				
			||||||
		case *http2.MetaHeadersFrame:
 | 
							case *http2.MetaHeadersFrame:
 | 
				
			||||||
			id := frame.Header().StreamID
 | 
								if t.operateHeaders(frame, handle) {
 | 
				
			||||||
			if id%2 != 1 || id <= t.maxStreamID {
 | 
					 | 
				
			||||||
				// illegal gRPC stream id.
 | 
					 | 
				
			||||||
				grpclog.Println("transport: http2Server.HandleStreams received an illegal stream id: ", id)
 | 
					 | 
				
			||||||
				t.Close()
 | 
									t.Close()
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			t.maxStreamID = id
 | 
					 | 
				
			||||||
			t.operateHeaders(frame, handle)
 | 
					 | 
				
			||||||
		case *http2.DataFrame:
 | 
							case *http2.DataFrame:
 | 
				
			||||||
			t.handleData(frame)
 | 
								t.handleData(frame)
 | 
				
			||||||
		case *http2.RSTStreamFrame:
 | 
							case *http2.RSTStreamFrame:
 | 
				
			||||||
@@ -282,7 +294,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) {
 | 
				
			|||||||
		case *http2.WindowUpdateFrame:
 | 
							case *http2.WindowUpdateFrame:
 | 
				
			||||||
			t.handleWindowUpdate(frame)
 | 
								t.handleWindowUpdate(frame)
 | 
				
			||||||
		case *http2.GoAwayFrame:
 | 
							case *http2.GoAwayFrame:
 | 
				
			||||||
			break
 | 
								// TODO: Handle GoAway from the client appropriately.
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			grpclog.Printf("transport: http2Server.HandleStreams found unhandled frame type %v.", frame)
 | 
								grpclog.Printf("transport: http2Server.HandleStreams found unhandled frame type %v.", frame)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -364,12 +376,8 @@ func (t *http2Server) handleData(f *http2.DataFrame) {
 | 
				
			|||||||
		// Received the end of stream from the client.
 | 
							// Received the end of stream from the client.
 | 
				
			||||||
		s.mu.Lock()
 | 
							s.mu.Lock()
 | 
				
			||||||
		if s.state != streamDone {
 | 
							if s.state != streamDone {
 | 
				
			||||||
			if s.state == streamWriteDone {
 | 
					 | 
				
			||||||
				s.state = streamDone
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
			s.state = streamReadDone
 | 
								s.state = streamReadDone
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		s.mu.Unlock()
 | 
							s.mu.Unlock()
 | 
				
			||||||
		s.write(recvMsg{err: io.EOF})
 | 
							s.write(recvMsg{err: io.EOF})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -440,7 +448,7 @@ func (t *http2Server) writeHeaders(s *Stream, b *bytes.Buffer, endStream bool) e
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			t.Close()
 | 
								t.Close()
 | 
				
			||||||
			return ConnectionErrorf("transport: %v", err)
 | 
								return ConnectionErrorf(true, err, "transport: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
@@ -455,7 +463,7 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	s.headerOk = true
 | 
						s.headerOk = true
 | 
				
			||||||
	s.mu.Unlock()
 | 
						s.mu.Unlock()
 | 
				
			||||||
	if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
 | 
						if _, err := wait(s.ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	t.hBuf.Reset()
 | 
						t.hBuf.Reset()
 | 
				
			||||||
@@ -495,7 +503,7 @@ func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc s
 | 
				
			|||||||
		headersSent = true
 | 
							headersSent = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s.mu.Unlock()
 | 
						s.mu.Unlock()
 | 
				
			||||||
	if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
 | 
						if _, err := wait(s.ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	t.hBuf.Reset()
 | 
						t.hBuf.Reset()
 | 
				
			||||||
@@ -508,7 +516,7 @@ func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc s
 | 
				
			|||||||
			Name:  "grpc-status",
 | 
								Name:  "grpc-status",
 | 
				
			||||||
			Value: strconv.Itoa(int(statusCode)),
 | 
								Value: strconv.Itoa(int(statusCode)),
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-message", Value: statusDesc})
 | 
						t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-message", Value: encodeGrpcMessage(statusDesc)})
 | 
				
			||||||
	// Attach the trailer metadata.
 | 
						// Attach the trailer metadata.
 | 
				
			||||||
	for k, v := range s.trailer {
 | 
						for k, v := range s.trailer {
 | 
				
			||||||
		// Clients don't tolerate reading restricted headers after some non restricted ones were sent.
 | 
							// Clients don't tolerate reading restricted headers after some non restricted ones were sent.
 | 
				
			||||||
@@ -544,7 +552,7 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	s.mu.Unlock()
 | 
						s.mu.Unlock()
 | 
				
			||||||
	if writeHeaderFrame {
 | 
						if writeHeaderFrame {
 | 
				
			||||||
		if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
 | 
							if _, err := wait(s.ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		t.hBuf.Reset()
 | 
							t.hBuf.Reset()
 | 
				
			||||||
@@ -560,7 +568,7 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		if err := t.framer.writeHeaders(false, p); err != nil {
 | 
							if err := t.framer.writeHeaders(false, p); err != nil {
 | 
				
			||||||
			t.Close()
 | 
								t.Close()
 | 
				
			||||||
			return ConnectionErrorf("transport: %v", err)
 | 
								return ConnectionErrorf(true, err, "transport: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		t.writableChan <- 0
 | 
							t.writableChan <- 0
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -572,13 +580,13 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
 | 
				
			|||||||
		size := http2MaxFrameLen
 | 
							size := http2MaxFrameLen
 | 
				
			||||||
		s.sendQuotaPool.add(0)
 | 
							s.sendQuotaPool.add(0)
 | 
				
			||||||
		// Wait until the stream has some quota to send the data.
 | 
							// Wait until the stream has some quota to send the data.
 | 
				
			||||||
		sq, err := wait(s.ctx, t.shutdownChan, s.sendQuotaPool.acquire())
 | 
							sq, err := wait(s.ctx, nil, nil, t.shutdownChan, s.sendQuotaPool.acquire())
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		t.sendQuotaPool.add(0)
 | 
							t.sendQuotaPool.add(0)
 | 
				
			||||||
		// Wait until the transport has some quota to send the data.
 | 
							// Wait until the transport has some quota to send the data.
 | 
				
			||||||
		tq, err := wait(s.ctx, t.shutdownChan, t.sendQuotaPool.acquire())
 | 
							tq, err := wait(s.ctx, nil, nil, t.shutdownChan, t.sendQuotaPool.acquire())
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			if _, ok := err.(StreamError); ok {
 | 
								if _, ok := err.(StreamError); ok {
 | 
				
			||||||
				t.sendQuotaPool.cancel()
 | 
									t.sendQuotaPool.cancel()
 | 
				
			||||||
@@ -604,7 +612,7 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
 | 
				
			|||||||
		t.framer.adjustNumWriters(1)
 | 
							t.framer.adjustNumWriters(1)
 | 
				
			||||||
		// Got some quota. Try to acquire writing privilege on the
 | 
							// Got some quota. Try to acquire writing privilege on the
 | 
				
			||||||
		// transport.
 | 
							// transport.
 | 
				
			||||||
		if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
 | 
							if _, err := wait(s.ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil {
 | 
				
			||||||
			if _, ok := err.(StreamError); ok {
 | 
								if _, ok := err.(StreamError); ok {
 | 
				
			||||||
				// Return the connection quota back.
 | 
									// Return the connection quota back.
 | 
				
			||||||
				t.sendQuotaPool.add(ps)
 | 
									t.sendQuotaPool.add(ps)
 | 
				
			||||||
@@ -634,7 +642,7 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		if err := t.framer.writeData(forceFlush, s.id, false, p); err != nil {
 | 
							if err := t.framer.writeData(forceFlush, s.id, false, p); err != nil {
 | 
				
			||||||
			t.Close()
 | 
								t.Close()
 | 
				
			||||||
			return ConnectionErrorf("transport: %v", err)
 | 
								return ConnectionErrorf(true, err, "transport: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if t.framer.adjustNumWriters(-1) == 0 {
 | 
							if t.framer.adjustNumWriters(-1) == 0 {
 | 
				
			||||||
			t.framer.flushWrite()
 | 
								t.framer.flushWrite()
 | 
				
			||||||
@@ -679,6 +687,17 @@ func (t *http2Server) controller() {
 | 
				
			|||||||
					}
 | 
										}
 | 
				
			||||||
				case *resetStream:
 | 
									case *resetStream:
 | 
				
			||||||
					t.framer.writeRSTStream(true, i.streamID, i.code)
 | 
										t.framer.writeRSTStream(true, i.streamID, i.code)
 | 
				
			||||||
 | 
									case *goAway:
 | 
				
			||||||
 | 
										t.mu.Lock()
 | 
				
			||||||
 | 
										if t.state == closing {
 | 
				
			||||||
 | 
											t.mu.Unlock()
 | 
				
			||||||
 | 
											// The transport is closing.
 | 
				
			||||||
 | 
											return
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										sid := t.maxStreamID
 | 
				
			||||||
 | 
										t.state = draining
 | 
				
			||||||
 | 
										t.mu.Unlock()
 | 
				
			||||||
 | 
										t.framer.writeGoAway(true, sid, http2.ErrCodeNo, nil)
 | 
				
			||||||
				case *flushIO:
 | 
									case *flushIO:
 | 
				
			||||||
					t.framer.flushWrite()
 | 
										t.framer.flushWrite()
 | 
				
			||||||
				case *ping:
 | 
									case *ping:
 | 
				
			||||||
@@ -724,6 +743,9 @@ func (t *http2Server) Close() (err error) {
 | 
				
			|||||||
func (t *http2Server) closeStream(s *Stream) {
 | 
					func (t *http2Server) closeStream(s *Stream) {
 | 
				
			||||||
	t.mu.Lock()
 | 
						t.mu.Lock()
 | 
				
			||||||
	delete(t.activeStreams, s.id)
 | 
						delete(t.activeStreams, s.id)
 | 
				
			||||||
 | 
						if t.state == draining && len(t.activeStreams) == 0 {
 | 
				
			||||||
 | 
							defer t.Close()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	t.mu.Unlock()
 | 
						t.mu.Unlock()
 | 
				
			||||||
	// In case stream sending and receiving are invoked in separate
 | 
						// In case stream sending and receiving are invoked in separate
 | 
				
			||||||
	// goroutines (e.g., bi-directional streaming), cancel needs to be
 | 
						// goroutines (e.g., bi-directional streaming), cancel needs to be
 | 
				
			||||||
@@ -746,3 +768,7 @@ func (t *http2Server) closeStream(s *Stream) {
 | 
				
			|||||||
func (t *http2Server) RemoteAddr() net.Addr {
 | 
					func (t *http2Server) RemoteAddr() net.Addr {
 | 
				
			||||||
	return t.conn.RemoteAddr()
 | 
						return t.conn.RemoteAddr()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (t *http2Server) Drain() {
 | 
				
			||||||
 | 
						t.controlBuf.put(&goAway{})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										83
									
								
								vendor/google.golang.org/grpc/transport/http_util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										83
									
								
								vendor/google.golang.org/grpc/transport/http_util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -35,6 +35,7 @@ package transport
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bufio"
 | 
						"bufio"
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
@@ -174,11 +175,11 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		d.statusCode = codes.Code(code)
 | 
							d.statusCode = codes.Code(code)
 | 
				
			||||||
	case "grpc-message":
 | 
						case "grpc-message":
 | 
				
			||||||
		d.statusDesc = f.Value
 | 
							d.statusDesc = decodeGrpcMessage(f.Value)
 | 
				
			||||||
	case "grpc-timeout":
 | 
						case "grpc-timeout":
 | 
				
			||||||
		d.timeoutSet = true
 | 
							d.timeoutSet = true
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
		d.timeout, err = timeoutDecode(f.Value)
 | 
							d.timeout, err = decodeTimeout(f.Value)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			d.setErr(StreamErrorf(codes.Internal, "transport: malformed time-out: %v", err))
 | 
								d.setErr(StreamErrorf(codes.Internal, "transport: malformed time-out: %v", err))
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
@@ -251,7 +252,7 @@ func div(d, r time.Duration) int64 {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO(zhaoq): It is the simplistic and not bandwidth efficient. Improve it.
 | 
					// TODO(zhaoq): It is the simplistic and not bandwidth efficient. Improve it.
 | 
				
			||||||
func timeoutEncode(t time.Duration) string {
 | 
					func encodeTimeout(t time.Duration) string {
 | 
				
			||||||
	if d := div(t, time.Nanosecond); d <= maxTimeoutValue {
 | 
						if d := div(t, time.Nanosecond); d <= maxTimeoutValue {
 | 
				
			||||||
		return strconv.FormatInt(d, 10) + "n"
 | 
							return strconv.FormatInt(d, 10) + "n"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -271,7 +272,7 @@ func timeoutEncode(t time.Duration) string {
 | 
				
			|||||||
	return strconv.FormatInt(div(t, time.Hour), 10) + "H"
 | 
						return strconv.FormatInt(div(t, time.Hour), 10) + "H"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func timeoutDecode(s string) (time.Duration, error) {
 | 
					func decodeTimeout(s string) (time.Duration, error) {
 | 
				
			||||||
	size := len(s)
 | 
						size := len(s)
 | 
				
			||||||
	if size < 2 {
 | 
						if size < 2 {
 | 
				
			||||||
		return 0, fmt.Errorf("transport: timeout string is too short: %q", s)
 | 
							return 0, fmt.Errorf("transport: timeout string is too short: %q", s)
 | 
				
			||||||
@@ -288,6 +289,80 @@ func timeoutDecode(s string) (time.Duration, error) {
 | 
				
			|||||||
	return d * time.Duration(t), nil
 | 
						return d * time.Duration(t), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						spaceByte   = ' '
 | 
				
			||||||
 | 
						tildaByte   = '~'
 | 
				
			||||||
 | 
						percentByte = '%'
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// encodeGrpcMessage is used to encode status code in header field
 | 
				
			||||||
 | 
					// "grpc-message".
 | 
				
			||||||
 | 
					// It checks to see if each individual byte in msg is an
 | 
				
			||||||
 | 
					// allowable byte, and then either percent encoding or passing it through.
 | 
				
			||||||
 | 
					// When percent encoding, the byte is converted into hexadecimal notation
 | 
				
			||||||
 | 
					// with a '%' prepended.
 | 
				
			||||||
 | 
					func encodeGrpcMessage(msg string) string {
 | 
				
			||||||
 | 
						if msg == "" {
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						lenMsg := len(msg)
 | 
				
			||||||
 | 
						for i := 0; i < lenMsg; i++ {
 | 
				
			||||||
 | 
							c := msg[i]
 | 
				
			||||||
 | 
							if !(c >= spaceByte && c < tildaByte && c != percentByte) {
 | 
				
			||||||
 | 
								return encodeGrpcMessageUnchecked(msg)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return msg
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func encodeGrpcMessageUnchecked(msg string) string {
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						lenMsg := len(msg)
 | 
				
			||||||
 | 
						for i := 0; i < lenMsg; i++ {
 | 
				
			||||||
 | 
							c := msg[i]
 | 
				
			||||||
 | 
							if c >= spaceByte && c < tildaByte && c != percentByte {
 | 
				
			||||||
 | 
								buf.WriteByte(c)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								buf.WriteString(fmt.Sprintf("%%%02X", c))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return buf.String()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// decodeGrpcMessage decodes the msg encoded by encodeGrpcMessage.
 | 
				
			||||||
 | 
					func decodeGrpcMessage(msg string) string {
 | 
				
			||||||
 | 
						if msg == "" {
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						lenMsg := len(msg)
 | 
				
			||||||
 | 
						for i := 0; i < lenMsg; i++ {
 | 
				
			||||||
 | 
							if msg[i] == percentByte && i+2 < lenMsg {
 | 
				
			||||||
 | 
								return decodeGrpcMessageUnchecked(msg)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return msg
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func decodeGrpcMessageUnchecked(msg string) string {
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						lenMsg := len(msg)
 | 
				
			||||||
 | 
						for i := 0; i < lenMsg; i++ {
 | 
				
			||||||
 | 
							c := msg[i]
 | 
				
			||||||
 | 
							if c == percentByte && i+2 < lenMsg {
 | 
				
			||||||
 | 
								parsed, err := strconv.ParseInt(msg[i+1:i+3], 16, 8)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									buf.WriteByte(c)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									buf.WriteByte(byte(parsed))
 | 
				
			||||||
 | 
									i += 2
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								buf.WriteByte(c)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return buf.String()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type framer struct {
 | 
					type framer struct {
 | 
				
			||||||
	numWriters int32
 | 
						numWriters int32
 | 
				
			||||||
	reader     io.Reader
 | 
						reader     io.Reader
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										51
									
								
								vendor/google.golang.org/grpc/transport/pre_go16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								vendor/google.golang.org/grpc/transport/pre_go16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					// +build !go1.6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016, Google Inc.
 | 
				
			||||||
 | 
					 * All rights reserved.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					 * modification, are permitted provided that the following conditions are
 | 
				
			||||||
 | 
					 * met:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					 * notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					 *     * Redistributions in binary form must reproduce the above
 | 
				
			||||||
 | 
					 * copyright notice, this list of conditions and the following disclaimer
 | 
				
			||||||
 | 
					 * in the documentation and/or other materials provided with the
 | 
				
			||||||
 | 
					 * distribution.
 | 
				
			||||||
 | 
					 *     * Neither the name of Google Inc. nor the names of its
 | 
				
			||||||
 | 
					 * contributors may be used to endorse or promote products derived from
 | 
				
			||||||
 | 
					 * this software without specific prior written permission.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
				
			||||||
 | 
					 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
				
			||||||
 | 
					 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
				
			||||||
 | 
					 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
				
			||||||
 | 
					 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
				
			||||||
 | 
					 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
 | 
					 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
				
			||||||
 | 
					 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package transport
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"golang.org/x/net/context"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dialContext connects to the address on the named network.
 | 
				
			||||||
 | 
					func dialContext(ctx context.Context, network, address string) (net.Conn, error) {
 | 
				
			||||||
 | 
						var dialer net.Dialer
 | 
				
			||||||
 | 
						if deadline, ok := ctx.Deadline(); ok {
 | 
				
			||||||
 | 
							dialer.Timeout = deadline.Sub(time.Now())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return dialer.Dial(network, address)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										85
									
								
								vendor/google.golang.org/grpc/transport/transport.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										85
									
								
								vendor/google.golang.org/grpc/transport/transport.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -44,7 +44,6 @@ import (
 | 
				
			|||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"golang.org/x/net/context"
 | 
						"golang.org/x/net/context"
 | 
				
			||||||
	"golang.org/x/net/trace"
 | 
						"golang.org/x/net/trace"
 | 
				
			||||||
@@ -121,6 +120,7 @@ func (b *recvBuffer) get() <-chan item {
 | 
				
			|||||||
// recvBuffer.
 | 
					// recvBuffer.
 | 
				
			||||||
type recvBufferReader struct {
 | 
					type recvBufferReader struct {
 | 
				
			||||||
	ctx    context.Context
 | 
						ctx    context.Context
 | 
				
			||||||
 | 
						goAway chan struct{}
 | 
				
			||||||
	recv   *recvBuffer
 | 
						recv   *recvBuffer
 | 
				
			||||||
	last   *bytes.Reader // Stores the remaining data in the previous calls.
 | 
						last   *bytes.Reader // Stores the remaining data in the previous calls.
 | 
				
			||||||
	err    error
 | 
						err    error
 | 
				
			||||||
@@ -141,6 +141,8 @@ func (r *recvBufferReader) Read(p []byte) (n int, err error) {
 | 
				
			|||||||
	select {
 | 
						select {
 | 
				
			||||||
	case <-r.ctx.Done():
 | 
						case <-r.ctx.Done():
 | 
				
			||||||
		return 0, ContextErr(r.ctx.Err())
 | 
							return 0, ContextErr(r.ctx.Err())
 | 
				
			||||||
 | 
						case <-r.goAway:
 | 
				
			||||||
 | 
							return 0, ErrStreamDrain
 | 
				
			||||||
	case i := <-r.recv.get():
 | 
						case i := <-r.recv.get():
 | 
				
			||||||
		r.recv.load()
 | 
							r.recv.load()
 | 
				
			||||||
		m := i.(*recvMsg)
 | 
							m := i.(*recvMsg)
 | 
				
			||||||
@@ -158,7 +160,7 @@ const (
 | 
				
			|||||||
	streamActive    streamState = iota
 | 
						streamActive    streamState = iota
 | 
				
			||||||
	streamWriteDone             // EndStream sent
 | 
						streamWriteDone             // EndStream sent
 | 
				
			||||||
	streamReadDone              // EndStream received
 | 
						streamReadDone              // EndStream received
 | 
				
			||||||
	streamDone                  // sendDone and recvDone or RSTStreamFrame is sent or received.
 | 
						streamDone                  // the entire stream is finished.
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Stream represents an RPC in the transport layer.
 | 
					// Stream represents an RPC in the transport layer.
 | 
				
			||||||
@@ -169,6 +171,10 @@ type Stream struct {
 | 
				
			|||||||
	// ctx is the associated context of the stream.
 | 
						// ctx is the associated context of the stream.
 | 
				
			||||||
	ctx    context.Context
 | 
						ctx    context.Context
 | 
				
			||||||
	cancel context.CancelFunc
 | 
						cancel context.CancelFunc
 | 
				
			||||||
 | 
						// done is closed when the final status arrives.
 | 
				
			||||||
 | 
						done chan struct{}
 | 
				
			||||||
 | 
						// goAway is closed when the server sent GoAways signal before this stream was initiated.
 | 
				
			||||||
 | 
						goAway chan struct{}
 | 
				
			||||||
	// method records the associated RPC method of the stream.
 | 
						// method records the associated RPC method of the stream.
 | 
				
			||||||
	method       string
 | 
						method       string
 | 
				
			||||||
	recvCompress string
 | 
						recvCompress string
 | 
				
			||||||
@@ -214,6 +220,18 @@ func (s *Stream) SetSendCompress(str string) {
 | 
				
			|||||||
	s.sendCompress = str
 | 
						s.sendCompress = str
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Done returns a chanel which is closed when it receives the final status
 | 
				
			||||||
 | 
					// from the server.
 | 
				
			||||||
 | 
					func (s *Stream) Done() <-chan struct{} {
 | 
				
			||||||
 | 
						return s.done
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GoAway returns a channel which is closed when the server sent GoAways signal
 | 
				
			||||||
 | 
					// before this stream was initiated.
 | 
				
			||||||
 | 
					func (s *Stream) GoAway() <-chan struct{} {
 | 
				
			||||||
 | 
						return s.goAway
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Header acquires the key-value pairs of header metadata once it
 | 
					// Header acquires the key-value pairs of header metadata once it
 | 
				
			||||||
// is available. It blocks until i) the metadata is ready or ii) there is no
 | 
					// is available. It blocks until i) the metadata is ready or ii) there is no
 | 
				
			||||||
// header metadata or iii) the stream is cancelled/expired.
 | 
					// header metadata or iii) the stream is cancelled/expired.
 | 
				
			||||||
@@ -221,6 +239,8 @@ func (s *Stream) Header() (metadata.MD, error) {
 | 
				
			|||||||
	select {
 | 
						select {
 | 
				
			||||||
	case <-s.ctx.Done():
 | 
						case <-s.ctx.Done():
 | 
				
			||||||
		return nil, ContextErr(s.ctx.Err())
 | 
							return nil, ContextErr(s.ctx.Err())
 | 
				
			||||||
 | 
						case <-s.goAway:
 | 
				
			||||||
 | 
							return nil, ErrStreamDrain
 | 
				
			||||||
	case <-s.headerChan:
 | 
						case <-s.headerChan:
 | 
				
			||||||
		return s.header.Copy(), nil
 | 
							return s.header.Copy(), nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -335,19 +355,17 @@ type ConnectOptions struct {
 | 
				
			|||||||
	// UserAgent is the application user agent.
 | 
						// UserAgent is the application user agent.
 | 
				
			||||||
	UserAgent string
 | 
						UserAgent string
 | 
				
			||||||
	// Dialer specifies how to dial a network address.
 | 
						// Dialer specifies how to dial a network address.
 | 
				
			||||||
	Dialer func(string, time.Duration) (net.Conn, error)
 | 
						Dialer func(context.Context, string) (net.Conn, error)
 | 
				
			||||||
	// PerRPCCredentials stores the PerRPCCredentials required to issue RPCs.
 | 
						// PerRPCCredentials stores the PerRPCCredentials required to issue RPCs.
 | 
				
			||||||
	PerRPCCredentials []credentials.PerRPCCredentials
 | 
						PerRPCCredentials []credentials.PerRPCCredentials
 | 
				
			||||||
	// TransportCredentials stores the Authenticator required to setup a client connection.
 | 
						// TransportCredentials stores the Authenticator required to setup a client connection.
 | 
				
			||||||
	TransportCredentials credentials.TransportCredentials
 | 
						TransportCredentials credentials.TransportCredentials
 | 
				
			||||||
	// Timeout specifies the timeout for dialing a ClientTransport.
 | 
					 | 
				
			||||||
	Timeout time.Duration
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewClientTransport establishes the transport with the required ConnectOptions
 | 
					// NewClientTransport establishes the transport with the required ConnectOptions
 | 
				
			||||||
// and returns it to the caller.
 | 
					// and returns it to the caller.
 | 
				
			||||||
func NewClientTransport(target string, opts *ConnectOptions) (ClientTransport, error) {
 | 
					func NewClientTransport(ctx context.Context, target string, opts ConnectOptions) (ClientTransport, error) {
 | 
				
			||||||
	return newHTTP2Client(target, opts)
 | 
						return newHTTP2Client(ctx, target, opts)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Options provides additional hints and information for message
 | 
					// Options provides additional hints and information for message
 | 
				
			||||||
@@ -417,6 +435,11 @@ type ClientTransport interface {
 | 
				
			|||||||
	// and create a new one) in error case. It should not return nil
 | 
						// and create a new one) in error case. It should not return nil
 | 
				
			||||||
	// once the transport is initiated.
 | 
						// once the transport is initiated.
 | 
				
			||||||
	Error() <-chan struct{}
 | 
						Error() <-chan struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// GoAway returns a channel that is closed when ClientTranspor
 | 
				
			||||||
 | 
						// receives the draining signal from the server (e.g., GOAWAY frame in
 | 
				
			||||||
 | 
						// HTTP/2).
 | 
				
			||||||
 | 
						GoAway() <-chan struct{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ServerTransport is the common interface for all gRPC server-side transport
 | 
					// ServerTransport is the common interface for all gRPC server-side transport
 | 
				
			||||||
@@ -448,6 +471,9 @@ type ServerTransport interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// RemoteAddr returns the remote network address.
 | 
						// RemoteAddr returns the remote network address.
 | 
				
			||||||
	RemoteAddr() net.Addr
 | 
						RemoteAddr() net.Addr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Drain notifies the client this ServerTransport stops accepting new RPCs.
 | 
				
			||||||
 | 
						Drain()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// StreamErrorf creates an StreamError with the specified error code and description.
 | 
					// StreamErrorf creates an StreamError with the specified error code and description.
 | 
				
			||||||
@@ -459,9 +485,11 @@ func StreamErrorf(c codes.Code, format string, a ...interface{}) StreamError {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ConnectionErrorf creates an ConnectionError with the specified error description.
 | 
					// ConnectionErrorf creates an ConnectionError with the specified error description.
 | 
				
			||||||
func ConnectionErrorf(format string, a ...interface{}) ConnectionError {
 | 
					func ConnectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError {
 | 
				
			||||||
	return ConnectionError{
 | 
						return ConnectionError{
 | 
				
			||||||
		Desc: fmt.Sprintf(format, a...),
 | 
							Desc: fmt.Sprintf(format, a...),
 | 
				
			||||||
 | 
							temp: temp,
 | 
				
			||||||
 | 
							err:  e,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -469,14 +497,36 @@ func ConnectionErrorf(format string, a ...interface{}) ConnectionError {
 | 
				
			|||||||
// entire connection and the retry of all the active streams.
 | 
					// entire connection and the retry of all the active streams.
 | 
				
			||||||
type ConnectionError struct {
 | 
					type ConnectionError struct {
 | 
				
			||||||
	Desc string
 | 
						Desc string
 | 
				
			||||||
 | 
						temp bool
 | 
				
			||||||
 | 
						err  error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e ConnectionError) Error() string {
 | 
					func (e ConnectionError) Error() string {
 | 
				
			||||||
	return fmt.Sprintf("connection error: desc = %q", e.Desc)
 | 
						return fmt.Sprintf("connection error: desc = %q", e.Desc)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ErrConnClosing indicates that the transport is closing.
 | 
					// Temporary indicates if this connection error is temporary or fatal.
 | 
				
			||||||
var ErrConnClosing = ConnectionError{Desc: "transport is closing"}
 | 
					func (e ConnectionError) Temporary() bool {
 | 
				
			||||||
 | 
						return e.temp
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Origin returns the original error of this connection error.
 | 
				
			||||||
 | 
					func (e ConnectionError) Origin() error {
 | 
				
			||||||
 | 
						// Never return nil error here.
 | 
				
			||||||
 | 
						// If the original error is nil, return itself.
 | 
				
			||||||
 | 
						if e.err == nil {
 | 
				
			||||||
 | 
							return e
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return e.err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						// ErrConnClosing indicates that the transport is closing.
 | 
				
			||||||
 | 
						ErrConnClosing = ConnectionError{Desc: "transport is closing", temp: true}
 | 
				
			||||||
 | 
						// ErrStreamDrain indicates that the stream is rejected by the server because
 | 
				
			||||||
 | 
						// the server stops accepting new RPCs.
 | 
				
			||||||
 | 
						ErrStreamDrain = StreamErrorf(codes.Unavailable, "the server stops accepting new RPCs")
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// StreamError is an error that only affects one stream within a connection.
 | 
					// StreamError is an error that only affects one stream within a connection.
 | 
				
			||||||
type StreamError struct {
 | 
					type StreamError struct {
 | 
				
			||||||
@@ -501,12 +551,25 @@ func ContextErr(err error) StreamError {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// wait blocks until it can receive from ctx.Done, closing, or proceed.
 | 
					// wait blocks until it can receive from ctx.Done, closing, or proceed.
 | 
				
			||||||
// If it receives from ctx.Done, it returns 0, the StreamError for ctx.Err.
 | 
					// If it receives from ctx.Done, it returns 0, the StreamError for ctx.Err.
 | 
				
			||||||
 | 
					// If it receives from done, it returns 0, io.EOF if ctx is not done; otherwise
 | 
				
			||||||
 | 
					// it return the StreamError for ctx.Err.
 | 
				
			||||||
 | 
					// If it receives from goAway, it returns 0, ErrStreamDrain.
 | 
				
			||||||
// If it receives from closing, it returns 0, ErrConnClosing.
 | 
					// If it receives from closing, it returns 0, ErrConnClosing.
 | 
				
			||||||
// If it receives from proceed, it returns the received integer, nil.
 | 
					// If it receives from proceed, it returns the received integer, nil.
 | 
				
			||||||
func wait(ctx context.Context, closing <-chan struct{}, proceed <-chan int) (int, error) {
 | 
					func wait(ctx context.Context, done, goAway, closing <-chan struct{}, proceed <-chan int) (int, error) {
 | 
				
			||||||
	select {
 | 
						select {
 | 
				
			||||||
	case <-ctx.Done():
 | 
						case <-ctx.Done():
 | 
				
			||||||
		return 0, ContextErr(ctx.Err())
 | 
							return 0, ContextErr(ctx.Err())
 | 
				
			||||||
 | 
						case <-done:
 | 
				
			||||||
 | 
							// User cancellation has precedence.
 | 
				
			||||||
 | 
							select {
 | 
				
			||||||
 | 
							case <-ctx.Done():
 | 
				
			||||||
 | 
								return 0, ContextErr(ctx.Err())
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return 0, io.EOF
 | 
				
			||||||
 | 
						case <-goAway:
 | 
				
			||||||
 | 
							return 0, ErrStreamDrain
 | 
				
			||||||
	case <-closing:
 | 
						case <-closing:
 | 
				
			||||||
		return 0, ErrConnClosing
 | 
							return 0, ErrConnClosing
 | 
				
			||||||
	case i := <-proceed:
 | 
						case i := <-proceed:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user