// 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 }