Example #1
0
func (cnn *serverConn) handle(chpv reflect.Value, name []byte) {

	handler := func(ws *websocket.Conn) {

		// send
		go func() {
			for {
				if v, ok := chpv.Recv(); ok {
					cnn.codec.Send(ws, v)
				} else {
					panic(Closed)
				}
			}
		}()

		// recieve
		for {
			v := reflect.New(chpv.Type().Elem())
			cnn.codec.Receive(ws, v.Interface())
			chpv.Send(reflect.Indirect(v))
		}
	}

	encodedName := base64.URLEncoding.EncodeToString(name)
	if _, ok := cnn.channels[encodedName]; !ok {
		cnn.channels[encodedName] = true
		pattern := fmt.Sprintf("/%s", encodedName)
		cnn.handlers.Handle(pattern, websocket.Handler(handler))
	}
}
Example #2
0
func doChanWrite(valCh, argVal reflect.Value) {
	chType := valCh.Type().Elem()
	if argVal.Type().ConvertibleTo(chType) {
		argVal = argVal.Convert(chType)
	}

	for {
		valCh.Send(argVal)
	}
}
Example #3
0
func pMapChanInt(inChan reflect.Value, f interface{}, outChan reflect.Value) {
	fVal := reflect.ValueOf(f)
	val, ok := inChan.Recv()
	for ok {
		results := fVal.Call([]reflect.Value{val})
		outChan.Send(results[0])
		val, ok = inChan.Recv()
	}
	outChan.Close()
}
Example #4
0
func sendKeyValues(outChan reflect.Value, key interface{}, valueType reflect.Type, values []interface{}) {
	sliceElementType := reflect.SliceOf(valueType)

	sliceLen := len(values)
	sliceValue := reflect.MakeSlice(sliceElementType, sliceLen, sliceLen)
	for i, value := range values {
		sliceValue.Index(i).Set(reflect.ValueOf(value))
	}

	outChan.Send(reflect.ValueOf(KeyValues{key, sliceValue.Interface()}))
}
Example #5
0
func pMapDrainOutChans(outChans []reflect.Value, resultChan reflect.Value) {
	numChans := len(outChans)
	idx := 0
	val, ok := outChans[idx].Recv()
	for ok {
		resultChan.Send(val)
		idx++
		val, ok = outChans[idx%numChans].Recv()
	}
	resultChan.Close()
}
Example #6
0
func mapWorker(fn reflect.Value, job chan []reflect.Value, res reflect.Value) {
	for {
		v, ok := <-job
		if !ok {
			break
		}
		if len(v) > 0 {
			r := fn.Call(v)
			res.Send(r[0])
		}
	}
}
Example #7
0
// the value over the outChan is always reflect.Value
// but the inner values are always actual interface{} object
func sendMapOutputs(outChan reflect.Value, values []reflect.Value) {
	if !outChan.IsValid() {
		return
	}
	if len(values) == 2 {
		outChan.Send(reflect.ValueOf(KeyValue{values[0].Interface(), values[1].Interface()}))
		return
	}
	if len(values) == 1 {
		outChan.Send(values[0])
		return
	}
}
Example #8
0
func (t *Transport) toChan(cid uint64, cval reflect.Value) error {
	// Type check! woo
	if cval.Kind() != reflect.Chan {
		return fmt.Errorf("fatchan: cannot connect a %s - must be a channel", cval.Type())
	}
	if cval.Type().ChanDir()&reflect.SendDir == 0 {
		return fmt.Errorf("fatchan: cannot connect a %s - recieve-only channel", cval.Type())
	}

	// Register our channel
	recv := make(chan []byte, 32)
	reg := &register{
		cid:  cid,
		data: recv,
		done: make(done, 1),
	}
	t.query <- reg
	<-reg.done
	sid, cid := t.sid, reg.cid

	go func() {
		// Close the channel when we return
		defer cval.Close() // TODO(kevlar): Catch close of closed channel?

		// Unregister the channel when we return
		defer func() {
			select {
			case t.msg <- &unregister{cid: cid}:
			case <-time.After(10 * time.Millisecond):
				// TODO(kevlar): Is this prefereable to closing the channel
				// and catching the panic?  I'm not sure.  Would it be possible
				// to use a WaitGroup to know when to close the query channel?
			}
		}()

		etyp := cval.Type().Elem()
		for data := range recv {
			t.debug("[%d] new data %q", cid, data)
			v := reflect.New(etyp).Elem()
			if err := t.decodeValue(bytes.NewReader(data), v); err != nil {
				t.err(sid, cid, err)
				return
			}
			t.debug("[%d] sending %#v", cid, v.Interface())
			cval.Send(v)
		}
	}()

	return nil
}
Example #9
0
func sendKeyValuesValues(outChan reflect.Value, key interface{},
	leftType reflect.Type, leftValues []interface{}, rightType reflect.Type, rightValues []interface{}) {

	slice1Len := len(leftValues)
	slice1Value := reflect.MakeSlice(reflect.SliceOf(leftType), slice1Len, slice1Len)
	for i, value := range leftValues {
		slice1Value.Index(i).Set(reflect.ValueOf(value))
	}

	slice2Len := len(rightValues)
	slice2Value := reflect.MakeSlice(reflect.SliceOf(rightType), slice2Len, slice2Len)
	for i, value := range rightValues {
		slice2Value.Index(i).Set(reflect.ValueOf(value))
	}

	outChan.Send(reflect.ValueOf(KeyValuesValues{key, slice1Value.Interface(), slice2Value.Interface()}))
}
Example #10
0
// the value over the outChan is always reflect.Value
// but the inner values are always actual interface{} object
func sendValues(outChan reflect.Value, values []reflect.Value) {
	var infs []interface{}
	for _, v := range values {
		infs = append(infs, v.Interface())
	}
	if !outChan.IsValid() {
		return
	}
	if len(infs) > 1 {
		outChan.Send(reflect.ValueOf(infs))
		return
	}
	if len(infs) == 1 {
		outChan.Send(reflect.ValueOf(infs[0]))
		return
	}
}
Example #11
0
func sendKeyValuesValues(outChan reflect.Value, key interface{}, valueType reflect.Type, values1, values2 []interface{}) {
	sliceType := reflect.SliceOf(valueType)

	slice1Len := len(values1)
	slice1Value := reflect.MakeSlice(sliceType, slice1Len, slice1Len)
	for i, value := range values1 {
		slice1Value.Index(i).Set(reflect.ValueOf(value))
	}

	slice2Len := len(values2)
	slice2Value := reflect.MakeSlice(sliceType, slice2Len, slice2Len)
	for i, value := range values2 {
		slice2Value.Index(i).Set(reflect.ValueOf(value))
	}

	outChan.Send(reflect.ValueOf(KeyValuesValues{key, slice1Value.Interface(), slice2Value.Interface()}))
}
Example #12
0
func (t *Transport) toChan(cval reflect.Value) (uint64, uint64, error) {
	sid, cid := t.sid, atomic.AddUint64(&t.nextCID, 1)

	// Type check! woo
	if cval.Kind() != reflect.Chan {
		return sid, cid, fmt.Errorf("fatchan: cannot connect a %s - must be a channel", cval.Type())
	}
	if cval.Type().ChanDir()&reflect.SendDir == 0 {
		return sid, cid, fmt.Errorf("fatchan: cannot connect a %s - recieve-only channel", cval.Type())
	}

	// Register our data
	recv := make(chan []byte, 32)
	t.reg <- register{cid, recv}

	// Peruse the element type
	etyp := cval.Type().Elem()

	go func() {
		defer cval.Close()
		defer func() {
			t.unreg <- unregister{cid}
		}()

		for data := range recv {
			v := reflect.New(etyp).Elem()
			if err := t.decodeValue(bytes.NewReader(data), v); err != nil {
				t.err(t.sid, cid, err)
				return
			}
			cval.Send(v)
		}
	}()

	return sid, cid, nil
}
Example #13
0
func send(outChan reflect.Value, values ...interface{}) {
	outChan.Send(reflect.ValueOf(values))
}
Example #14
0
// run runs the network and waits for all processes to finish.
func (n *Graph) run() {
	// Add processes to the waitgroup before starting them
	nump := len(n.procs)
	n.waitGrp.Add(nump)
	for _, v := range n.procs {
		// Check if it is a net or proc
		r := reflect.ValueOf(v).Elem()
		if r.FieldByName("Graph").IsValid() {
			RunNet(v)
		} else {
			RunProc(v)
		}
	}
	n.isRunning = true

	// Send initial IPs
	for _, ip := range n.iips {
		// Get the reciever port
		var rport reflect.Value
		found := false

		// Try to find it among network inports
		for _, inPort := range n.inPorts {
			if inPort.proc == ip.proc && inPort.port == ip.port {
				rport = inPort.channel
				found = true
				break
			}
		}

		if !found {
			// Try to find among connections
			for _, conn := range n.connections {
				if conn.tgt.Proc == ip.proc && conn.tgt.Port == ip.port {
					rport = conn.channel
					found = true
					break
				}
			}
		}

		if !found {
			// Try to find a proc and attach a new channel to it
			for procName, proc := range n.procs {
				if procName == ip.proc {
					// Check if receiver is a net
					rv := reflect.ValueOf(proc).Elem()
					var rnet reflect.Value
					if rv.Type().Name() == "Graph" {
						rnet = rv
					} else {
						rnet = rv.FieldByName("Graph")
					}
					if rnet.IsValid() {
						if pm, isPm := rnet.Addr().Interface().(portMapper); isPm {
							rport = pm.getInPort(ip.port)
						}
					} else {
						// Receiver is a proc
						rport = rv.FieldByName(ip.port)
					}

					// Validate receiver port
					rtport := rport.Type()
					if rtport.Kind() != reflect.Chan || rtport.ChanDir()&reflect.RecvDir == 0 {
						panic(ip.proc + "." + ip.port + " is not a valid input channel")
					}
					var channel reflect.Value

					// Make a channel of an appropriate type
					chanType := reflect.ChanOf(reflect.BothDir, rtport.Elem())
					channel = reflect.MakeChan(chanType, DefaultBufferSize)
					// Set the channel
					if rport.CanSet() {
						rport.Set(channel)
					} else {
						panic(ip.proc + "." + ip.port + " is not settable")
					}

					// Use the new channel to send the IIP
					rport = channel
					found = true
					break
				}
			}
		}

		if found {
			// Send data to the port
			rport.Send(reflect.ValueOf(ip.data))
		} else {
			panic("IIP target not found: " + ip.proc + "." + ip.port)
		}
	}

	// Let the outside world know that the network is ready
	close(n.ready)

	// Wait for all processes to terminate
	n.waitGrp.Wait()
	n.isRunning = false
	// Check if there is a parent net
	if n.Net != nil {
		// Notify parent of finish
		n.Net.waitGrp.Done()
	}
}
Example #15
0
func (f decFnInfo) kSlice(rv reflect.Value) {
	// A slice can be set from a map or array in stream.
	// This way, the order can be kept (as order is lost with map).
	ti := f.ti
	d := f.d
	if f.dd.IsContainerType(valueTypeBytes) || f.dd.IsContainerType(valueTypeString) {
		if ti.rtid == uint8SliceTypId || ti.rt.Elem().Kind() == reflect.Uint8 {
			if f.seq == seqTypeChan {
				bs2 := f.dd.DecodeBytes(nil, false, true)
				ch := rv.Interface().(chan<- byte)
				for _, b := range bs2 {
					ch <- b
				}
			} else {
				rvbs := rv.Bytes()
				bs2 := f.dd.DecodeBytes(rvbs, false, false)
				if rvbs == nil && bs2 != nil || rvbs != nil && bs2 == nil || len(bs2) != len(rvbs) {
					if rv.CanSet() {
						rv.SetBytes(bs2)
					} else {
						copy(rvbs, bs2)
					}
				}
			}
			return
		}
	}

	// array := f.seq == seqTypeChan

	slh, containerLenS := d.decSliceHelperStart()

	// an array can never return a nil slice. so no need to check f.array here.
	if rv.IsNil() {
		// either chan or slice
		if f.seq == seqTypeSlice {
			if containerLenS <= 0 {
				rv.Set(reflect.MakeSlice(ti.rt, 0, 0))
			} else {
				rv.Set(reflect.MakeSlice(ti.rt, containerLenS, containerLenS))
			}
		} else if f.seq == seqTypeChan {
			if containerLenS <= 0 {
				rv.Set(reflect.MakeChan(ti.rt, 0))
			} else {
				rv.Set(reflect.MakeChan(ti.rt, containerLenS))
			}
		}
	}

	rvlen := rv.Len()
	if containerLenS == 0 {
		if f.seq == seqTypeSlice && rvlen != 0 {
			rv.SetLen(0)
		}
		// slh.End() // f.dd.ReadArrayEnd()
		return
	}

	rtelem0 := ti.rt.Elem()
	rtelem := rtelem0
	for rtelem.Kind() == reflect.Ptr {
		rtelem = rtelem.Elem()
	}
	fn := d.getDecFn(rtelem, true, true)

	rv0 := rv
	rvChanged := false

	rvcap := rv.Cap()

	// for j := 0; j < containerLenS; j++ {

	hasLen := containerLenS >= 0
	if hasLen {
		if f.seq == seqTypeChan {
			// handle chan specially:
			for j := 0; j < containerLenS; j++ {
				rv0 := reflect.New(rtelem0).Elem()
				d.decodeValue(rv0, fn)
				rv.Send(rv0)
			}
		} else {
			numToRead := containerLenS
			if containerLenS > rvcap {
				if f.seq == seqTypeArray {
					d.arrayCannotExpand(rv.Len(), containerLenS)
					numToRead = rvlen
				} else {
					rv = reflect.MakeSlice(ti.rt, containerLenS, containerLenS)
					if rvlen > 0 && !isMutableKind(ti.rt.Kind()) {
						rv1 := rv0
						rv1.SetLen(rvcap)
						reflect.Copy(rv, rv1)
					}
					rvChanged = true
					rvlen = containerLenS
				}
			} else if containerLenS != rvlen {
				rv.SetLen(containerLenS)
				rvlen = containerLenS
			}
			j := 0
			for ; j < numToRead; j++ {
				d.decodeValue(rv.Index(j), fn)
			}
			if f.seq == seqTypeArray {
				for ; j < containerLenS; j++ {
					d.swallow()
				}
			}
		}
	} else {
		for j := 0; !f.dd.CheckBreak(); j++ {
			var decodeIntoBlank bool
			// if indefinite, etc, then expand the slice if necessary
			if j >= rvlen {
				if f.seq == seqTypeArray {
					d.arrayCannotExpand(rvlen, j+1)
					decodeIntoBlank = true
				} else if f.seq == seqTypeSlice {
					rv = reflect.Append(rv, reflect.Zero(rtelem0))
					rvlen++
					rvChanged = true
				}
			}
			if j > 0 {
				slh.Sep(j)
			}
			if f.seq == seqTypeChan {
				rv0 := reflect.New(rtelem0).Elem()
				d.decodeValue(rv0, fn)
				rv.Send(rv0)
			} else if decodeIntoBlank {
				d.swallow()
			} else {
				d.decodeValue(rv.Index(j), fn)
			}
		}
		slh.End()
	}

	if rvChanged {
		rv0.Set(rv)
	}
}
Example #16
0
func (f *decFnInfo) kSlice(rv reflect.Value) {
	// A slice can be set from a map or array in stream.
	// This way, the order can be kept (as order is lost with map).
	ti := f.ti
	d := f.d
	dd := d.d
	rtelem0 := ti.rt.Elem()

	if dd.IsContainerType(valueTypeBytes) || dd.IsContainerType(valueTypeString) {
		if ti.rtid == uint8SliceTypId || rtelem0.Kind() == reflect.Uint8 {
			if f.seq == seqTypeChan {
				bs2 := dd.DecodeBytes(nil, false, true)
				ch := rv.Interface().(chan<- byte)
				for _, b := range bs2 {
					ch <- b
				}
			} else {
				rvbs := rv.Bytes()
				bs2 := dd.DecodeBytes(rvbs, false, false)
				if rvbs == nil && bs2 != nil || rvbs != nil && bs2 == nil || len(bs2) != len(rvbs) {
					if rv.CanSet() {
						rv.SetBytes(bs2)
					} else {
						copy(rvbs, bs2)
					}
				}
			}
			return
		}
	}

	// array := f.seq == seqTypeChan

	slh, containerLenS := d.decSliceHelperStart()

	var rvlen, numToRead int
	var truncated bool // says that the len of the sequence is not same as the expected number of elements.

	numToRead = containerLenS // if truncated, reset numToRead

	// an array can never return a nil slice. so no need to check f.array here.
	if rv.IsNil() {
		// either chan or slice
		if rvlen, truncated = decInferLen(containerLenS, f.d.h.MaxInitLen, int(rtelem0.Size())); truncated {
			numToRead = rvlen
		}
		if f.seq == seqTypeSlice {
			rv.Set(reflect.MakeSlice(ti.rt, rvlen, rvlen))
		} else if f.seq == seqTypeChan {
			rv.Set(reflect.MakeChan(ti.rt, rvlen))
		}
	} else {
		rvlen = rv.Len()
	}

	if containerLenS == 0 {
		if f.seq == seqTypeSlice && rvlen != 0 {
			rv.SetLen(0)
		}
		// dd.ReadEnd()
		return
	}

	rtelem := rtelem0
	for rtelem.Kind() == reflect.Ptr {
		rtelem = rtelem.Elem()
	}
	fn := d.getDecFn(rtelem, true, true)

	var rv0, rv9 reflect.Value
	rv0 = rv
	rvChanged := false

	rvcap := rv.Cap()

	// for j := 0; j < containerLenS; j++ {

	if containerLenS >= 0 { // hasLen
		if f.seq == seqTypeChan {
			// handle chan specially:
			for j := 0; j < containerLenS; j++ {
				rv9 = reflect.New(rtelem0).Elem()
				d.decodeValue(rv9, fn)
				rv.Send(rv9)
			}
		} else { // slice or array
			if containerLenS > rvcap {
				if f.seq == seqTypeArray {
					d.arrayCannotExpand(rvlen, containerLenS)
				} else {
					oldRvlenGtZero := rvlen > 0
					rvlen, truncated = decInferLen(containerLenS, f.d.h.MaxInitLen, int(rtelem0.Size()))
					rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
					if oldRvlenGtZero && !isImmutableKind(rtelem0.Kind()) {
						reflect.Copy(rv, rv0) // only copy up to length NOT cap i.e. rv0.Slice(0, rvcap)
					}
					rvChanged = true
				}
				numToRead = rvlen
			} else if containerLenS != rvlen {
				if f.seq == seqTypeSlice {
					rv.SetLen(containerLenS)
					rvlen = containerLenS
				}
			}
			j := 0
			// we read up to the numToRead
			for ; j < numToRead; j++ {
				d.decodeValue(rv.Index(j), fn)
			}

			// if slice, expand and read up to containerLenS (or EOF) iff truncated
			// if array, swallow all the rest.

			if f.seq == seqTypeArray {
				for ; j < containerLenS; j++ {
					d.swallow()
				}
			} else if truncated { // slice was truncated, as chan NOT in this block
				for ; j < containerLenS; j++ {
					rv = expandSliceValue(rv, 1)
					rv9 = rv.Index(j)
					if resetSliceElemToZeroValue {
						rv9.Set(reflect.Zero(rtelem0))
					}
					d.decodeValue(rv9, fn)
				}
			}
		}
	} else {
		for j := 0; !dd.CheckBreak(); j++ {
			var decodeIntoBlank bool
			// if indefinite, etc, then expand the slice if necessary
			if j >= rvlen {
				if f.seq == seqTypeArray {
					d.arrayCannotExpand(rvlen, j+1)
					decodeIntoBlank = true
				} else if f.seq == seqTypeSlice {
					// rv = reflect.Append(rv, reflect.Zero(rtelem0)) // uses append logic, plus varargs
					rv = expandSliceValue(rv, 1)
					rv9 = rv.Index(j)
					// rv.Index(rv.Len() - 1).Set(reflect.Zero(rtelem0))
					if resetSliceElemToZeroValue {
						rv9.Set(reflect.Zero(rtelem0))
					}
					rvlen++
					rvChanged = true
				}
			} else if f.seq != seqTypeChan { // slice or array
				rv9 = rv.Index(j)
			}
			if f.seq == seqTypeChan {
				rv9 = reflect.New(rtelem0).Elem()
				d.decodeValue(rv9, fn)
				rv.Send(rv9)
			} else if decodeIntoBlank {
				d.swallow()
			} else { // seqTypeSlice
				d.decodeValue(rv9, fn)
			}
		}
		slh.End()
	}

	if rvChanged {
		rv0.Set(rv)
	}
}
Example #17
0
func sendKeyValueValue(outChan reflect.Value, key, a, b interface{}) {
	outChan.Send(reflect.ValueOf(KeyValueValue{key, a, b}))
}