Beispiel #1
0
func (this *FunServantImpl) Lock(ctx *rpc.Context,
	reason string, key string) (r bool, ex error) {
	const IDENT = "lock"

	svtStats.inc(IDENT)
	profiler, err := this.getSession(ctx).startProfiler()
	if err != nil {
		ex = err
		return
	}

	var peer string
	if ctx.IsSetSticky() && *ctx.Sticky {
		svtStats.incPeerCall()

		r = this.lk.Lock(key)
	} else {
		svt, err := this.proxy.ServantByKey(key) // FIXME add prefix?
		if err != nil {
			ex = err
			if svt != nil {
				if proxy.IsIoError(err) {
					svt.Close()
				}
				svt.Recycle()
			}
			return
		}

		if svt == proxy.Self {
			r = this.lk.Lock(key)
		} else {
			svtStats.incCallPeer()

			peer = svt.Addr()
			svt.HijackContext(ctx)
			r, ex = svt.Lock(ctx, reason, key)
			if ex != nil {
				if proxy.IsIoError(ex) {
					svt.Close()
				}
			}

			svt.Recycle()
		}
	}

	profiler.do(IDENT, ctx, "P=%s {reason^%s key^%s} {r^%v}",
		peer, reason, key, r)

	if !r {
		log.Warn("P=%s lock failed: {reason^%s key^%s}", peer, reason, key)
	}

	return
}
Beispiel #2
0
func (this *FunServantImpl) Unlock(ctx *rpc.Context,
	reason string, key string) (ex error) {
	const IDENT = "unlock"

	svtStats.inc(IDENT)
	profiler, err := this.getSession(ctx).startProfiler()
	if err != nil {
		ex = err
		return
	}

	var peer string
	if ctx.IsSetSticky() && *ctx.Sticky {
		svtStats.incPeerCall()

		this.lk.Unlock(key)
	} else {
		svt, err := this.proxy.ServantByKey(key)
		if err != nil {
			ex = err
			if svt != nil {
				if proxy.IsIoError(err) {
					svt.Close()
				}
				svt.Recycle()
			}
			return
		}

		if svt == proxy.Self {
			this.lk.Unlock(key)
		} else {
			svtStats.incCallPeer()

			peer = svt.Addr()
			svt.HijackContext(ctx)
			ex = svt.Unlock(ctx, reason, key)
			if ex != nil {
				if proxy.IsIoError(ex) {
					svt.Close()
				}
			}

			svt.Recycle()
		}
	}

	profiler.do(IDENT, ctx, "P=%s {reason^%s key^%s}",
		peer, reason, key)
	return
}
Beispiel #3
0
func (this *FunServantImpl) MyEvict(ctx *rpc.Context,
	cacheKey string) (ex error) {
	const IDENT = "my.evict"

	svtStats.inc(IDENT)

	profiler, err := this.getSession(ctx).startProfiler()
	if err != nil {
		ex = err
		return
	}

	var peer string
	if ctx.IsSetSticky() && *ctx.Sticky {
		svtStats.incPeerCall()
		this.dbCacheStore.Del(cacheKey)
	} else {
		svt, err := this.proxy.ServantByKey(cacheKey)
		if err != nil {
			ex = err
			if svt != nil {
				if proxy.IsIoError(err) {
					svt.Close()
				}
				svt.Recycle()
			}
			return
		}

		if svt == proxy.Self {
			this.dbCacheStore.Del(cacheKey)
		} else {
			svtStats.incCallPeer()

			peer = svt.Addr()
			svt.HijackContext(ctx)
			ex = svt.MyEvict(ctx, cacheKey)
			if ex != nil {
				if proxy.IsIoError(ex) {
					svt.Close()
				}
			}

			svt.Recycle()
		}
	}

	profiler.do(IDENT, ctx, "{key^%s} {p^%s}", cacheKey, peer)

	return
}
Beispiel #4
0
func main() {
	cf := config.NewDefaultProxy()
	cf.PoolCapacity = 2
	peer := proxy.New(cf)

	for {
		time.Sleep(time.Duration(interval) * time.Second)
		fmt.Println()

		client, err := peer.ServantByAddr(host + ":" + port)
		if err != nil {
			fmt.Println(err)
			continue
		}

		ctx := rpc.NewContext()
		ctx.Reason = "broken.test"
		ctx.Rid = time.Now().UnixNano()
		pong, err := client.Ping(ctx)
		if err != nil {
			fmt.Println("err:", err)

			if proxy.IsIoError(err) {
				client.Close()
			}
		} else {
			fmt.Println(pong)
		}

		client.Recycle()
	}

}
Beispiel #5
0
func (this *FunServantImpl) MyQuery(ctx *rpc.Context, pool string, table string,
	hintId int64, sql string, args []string, cacheKey string) (r *rpc.MysqlResult,
	ex error) {
	const IDENT = "my.query"

	profiler, err := this.getSession(ctx).startProfiler()
	if err != nil {
		ex = err
		return
	}

	svtStats.inc(IDENT)

	var (
		cacheKeyHash = cacheKey
		peer         string
		rows         int
	)

	if cacheKey != "" && this.conf.Mysql.CacheKeyHash {
		hashSum := sha1.Sum([]byte(cacheKey)) // sha1.Size
		cacheKeyHash = string(hashSum[:])
	}

	if cacheKeyHash == "" {
		r, ex = this.doMyQuery(IDENT, ctx, pool, table, hintId,
			sql, args, cacheKeyHash)
		rows = len(r.Rows)
		if r.RowsAffected > 0 {
			rows = int(r.RowsAffected)
		}
	} else {
		if ctx.IsSetSticky() && *ctx.Sticky {
			svtStats.incPeerCall()

			r, ex = this.doMyQuery(IDENT, ctx, pool, table, hintId,
				sql, args, cacheKeyHash)
			rows = len(r.Rows)
			if r.RowsAffected > 0 {
				rows = int(r.RowsAffected)
			}
		} else {
			svt, err := this.proxy.ServantByKey(cacheKey)
			if err != nil {
				ex = err
				if svt != nil {
					if proxy.IsIoError(err) {
						svt.Close()
					}
					svt.Recycle()
				}
				return
			}

			if svt == proxy.Self {
				r, ex = this.doMyQuery(IDENT, ctx, pool, table, hintId,
					sql, args, cacheKeyHash)
				rows = len(r.Rows)
				if r.RowsAffected > 0 {
					rows = int(r.RowsAffected)
				}
			} else {
				// dispatch to peer
				svtStats.incCallPeer()

				peer = svt.Addr()
				svt.HijackContext(ctx)
				r, ex = svt.MyQuery(ctx, pool, table, hintId, sql, args, cacheKey)
				if ex != nil {
					if proxy.IsIoError(ex) {
						svt.Close()
					}
				} else {
					rows = len(r.Rows)
					if r.RowsAffected > 0 {
						rows = int(r.RowsAffected)
					}
				}

				svt.Recycle() // NEVER forget about this
			}
		}
	}

	if ex != nil {
		profiler.do(IDENT, ctx,
			"P=%s {cache^%s pool^%s table^%s id^%d sql^%s args^%+v} {err^%s}",
			peer, cacheKey, pool, table, hintId, sql, args, ex)
	} else {
		profiler.do(IDENT, ctx,
			"P=%s {cache^%s pool^%s table^%s id^%d sql^%s args^%+v} {rows^%d r^%+v}",
			peer, cacheKey, pool, table, hintId, sql, args, rows, *r)
	}

	return
}