Implement server to client ChannelDone
This commit is contained in:
		@@ -111,6 +111,18 @@ func (c *Client) Call(rcvr, method string, arg interface{}, ret interface{}) err
 | 
			
		||||
			chElemType := retVal.Type().Elem()
 | 
			
		||||
			// For every value received from channel
 | 
			
		||||
			for val := range c.chs[chID] {
 | 
			
		||||
				if val.ChannelDone {
 | 
			
		||||
					// Close and delete channel
 | 
			
		||||
					c.chMtx.Lock()
 | 
			
		||||
					close(c.chs[chID])
 | 
			
		||||
					delete(c.chs, chID)
 | 
			
		||||
					c.chMtx.Unlock()
 | 
			
		||||
 | 
			
		||||
					// Close return channel
 | 
			
		||||
					retVal.Close()
 | 
			
		||||
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
				// Get reflect value from channel response
 | 
			
		||||
				rVal := reflect.ValueOf(val.Return)
 | 
			
		||||
 | 
			
		||||
@@ -124,25 +136,25 @@ func (c *Client) Call(rcvr, method string, arg interface{}, ret interface{}) err
 | 
			
		||||
					rVal = newVal
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Try to read from the channel
 | 
			
		||||
				recvVal, ok := retVal.TryRecv()
 | 
			
		||||
				// IF the channel cannot be read but the value is valid,
 | 
			
		||||
				// the channel must be closed
 | 
			
		||||
				if !ok && recvVal.IsValid() {
 | 
			
		||||
					// Send done signal
 | 
			
		||||
					c.Call("lrpc", "ChannelDone", idStr, nil)
 | 
			
		||||
					// Close and delete channel
 | 
			
		||||
					c.chMtx.Lock()
 | 
			
		||||
					close(c.chs[chID])
 | 
			
		||||
					delete(c.chs, chID)
 | 
			
		||||
					c.chMtx.Unlock()
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Send value to channel
 | 
			
		||||
				retVal.Send(rVal)
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
 | 
			
		||||
		go func() {
 | 
			
		||||
			for {
 | 
			
		||||
				val, ok := retVal.Recv()
 | 
			
		||||
				if !ok && val.IsValid() {
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			c.Call("lrpc", "ChannelDone", id, nil)
 | 
			
		||||
			// Close and delete channel
 | 
			
		||||
			c.chMtx.Lock()
 | 
			
		||||
			close(c.chs[chID])
 | 
			
		||||
			delete(c.chs, chID)
 | 
			
		||||
			c.chMtx.Unlock()
 | 
			
		||||
		}()
 | 
			
		||||
	} else {
 | 
			
		||||
		// IF return value is not a pointer, return error
 | 
			
		||||
		if retVal.Kind() != reflect.Ptr {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user