Exemplo n.º 1
0
// Read is used to perform a read-only transaction that doesn't modify the state
// store. This is much more scaleable since it doesn't go through Raft and
// supports staleness, so this should be preferred if you're just performing
// reads.
func (t *Txn) Read(args *structs.TxnReadRequest, reply *structs.TxnReadResponse) error {
	if done, err := t.srv.forward("Txn.Read", args, args, reply); done {
		return err
	}
	defer metrics.MeasureSince([]string{"consul", "txn", "read"}, time.Now())

	// We have to do this ourselves since we are not doing a blocking RPC.
	t.srv.setQueryMeta(&reply.QueryMeta)
	if args.RequireConsistent {
		if err := t.srv.consistentRead(); err != nil {
			return err
		}
	}

	// Run the pre-checks before we perform the read.
	acl, err := t.srv.resolveToken(args.Token)
	if err != nil {
		return err
	}
	reply.Errors = t.preCheck(acl, args.Ops)
	if len(reply.Errors) > 0 {
		return nil
	}

	// Run the read transaction.
	state := t.srv.fsm.State()
	reply.Results, reply.Errors = state.TxnRO(args.Ops)
	if acl != nil {
		reply.Results = FilterTxnResults(acl, reply.Results)
	}
	return nil
}