2019-01-25 03:43:26 +08:00
2017-05-26 04:48:44 +08:00
/*
* MasterProxyInterface . h
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013 - 2018 Apple Inc . and the FoundationDB project authors
2018-02-22 02:25:11 +08:00
*
2017-05-26 04:48:44 +08:00
* Licensed under the Apache License , Version 2.0 ( the " License " ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
2018-02-22 02:25:11 +08:00
*
2017-05-26 04:48:44 +08:00
* http : //www.apache.org/licenses/LICENSE-2.0
2018-02-22 02:25:11 +08:00
*
2017-05-26 04:48:44 +08:00
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
# ifndef FDBCLIENT_MASTERPROXYINTERFACE_H
# define FDBCLIENT_MASTERPROXYINTERFACE_H
# pragma once
2018-10-20 01:30:13 +08:00
# include "fdbclient/FDBTypes.h"
# include "fdbclient/StorageServerInterface.h"
# include "fdbclient/CommitTransaction.h"
2017-05-26 04:48:44 +08:00
2018-12-01 02:46:04 +08:00
# include "flow/Stats.h"
2017-05-26 04:48:44 +08:00
struct MasterProxyInterface {
enum { LocationAwareLoadBalance = 1 } ;
2018-11-03 04:15:09 +08:00
enum { AlwaysFresh = 1 } ;
2017-05-26 04:48:44 +08:00
LocalityData locality ;
RequestStream < struct CommitTransactionRequest > commit ;
RequestStream < struct GetReadVersionRequest > getConsistentReadVersion ; // Returns a version which (1) is committed, and (2) is >= the latest version reported committed (by a commit response) when this request was sent
// (at some point between when this request is sent and when its response is received, the latest version reported committed)
2017-12-10 08:10:22 +08:00
RequestStream < struct GetKeyServerLocationsRequest > getKeyServersLocations ;
2017-05-26 04:48:44 +08:00
RequestStream < struct GetStorageServerRejoinInfoRequest > getStorageServerRejoinInfo ;
RequestStream < ReplyPromise < Void > > waitFailure ;
RequestStream < struct GetRawCommittedVersionRequest > getRawCommittedVersion ;
RequestStream < struct TxnStateRequest > txnState ;
2019-02-02 02:58:42 +08:00
RequestStream < struct GetHealthMetricsRequest > getHealthMetrics ;
2017-05-26 04:48:44 +08:00
UID id ( ) const { return commit . getEndpoint ( ) . token ; }
std : : string toString ( ) const { return id ( ) . shortString ( ) ; }
bool operator = = ( MasterProxyInterface const & r ) const { return id ( ) = = r . id ( ) ; }
bool operator ! = ( MasterProxyInterface const & r ) const { return id ( ) ! = r . id ( ) ; }
2018-10-31 04:44:37 +08:00
NetworkAddress address ( ) const { return commit . getEndpoint ( ) . getPrimaryAddress ( ) ; }
2017-05-26 04:48:44 +08:00
template < class Archive >
void serialize ( Archive & ar ) {
2019-02-02 02:58:42 +08:00
serializer ( ar , locality , commit , getConsistentReadVersion , getKeyServersLocations ,
waitFailure , getStorageServerRejoinInfo , getRawCommittedVersion ,
2019-02-24 02:13:43 +08:00
txnState , getHealthMetrics ) ;
2017-05-26 04:48:44 +08:00
}
void initEndpoints ( ) {
getConsistentReadVersion . getEndpoint ( TaskProxyGetConsistentReadVersion ) ;
getRawCommittedVersion . getEndpoint ( TaskProxyGetRawCommittedVersion ) ;
2018-06-02 06:21:40 +08:00
commit . getEndpoint ( TaskProxyCommitDispatcher ) ;
2018-08-01 07:57:23 +08:00
//getKeyServersLocations.getEndpoint(TaskProxyGetKeyServersLocations); //do not increase the priority of these requests, because clients cans bring down the cluster with too many of these messages.
2017-05-26 04:48:44 +08:00
}
} ;
struct CommitID {
Version version ; // returns invalidVersion if transaction conflicts
uint16_t txnBatchId ;
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , version , txnBatchId ) ;
2017-05-26 04:48:44 +08:00
}
CommitID ( ) : version ( invalidVersion ) , txnBatchId ( 0 ) { }
CommitID ( Version version , uint16_t txnBatchId ) : version ( version ) , txnBatchId ( txnBatchId ) { }
} ;
2018-12-01 02:46:04 +08:00
struct CommitTransactionRequest : TimedRequest {
2018-02-10 10:21:29 +08:00
enum {
FLAG_IS_LOCK_AWARE = 0x1 ,
FLAG_FIRST_IN_BATCH = 0x2
} ;
bool isLockAware ( ) const { return flags & FLAG_IS_LOCK_AWARE ; }
bool firstInBatch ( ) const { return flags & FLAG_FIRST_IN_BATCH ; }
2017-05-26 04:48:44 +08:00
Arena arena ;
CommitTransactionRef transaction ;
2018-02-10 10:21:29 +08:00
ReplyPromise < CommitID > reply ;
uint32_t flags ;
2017-05-26 04:48:44 +08:00
Optional < UID > debugID ;
2018-02-10 10:21:29 +08:00
CommitTransactionRequest ( ) : flags ( 0 ) { }
2017-05-26 04:48:44 +08:00
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , transaction , reply , arena , flags , debugID ) ;
2017-05-26 04:48:44 +08:00
}
} ;
2018-11-03 04:15:09 +08:00
static inline int getBytes ( CommitTransactionRequest const & r ) {
2017-05-26 04:48:44 +08:00
// SOMEDAY: Optimize
//return r.arena.getSize(); // NOT correct because arena can be shared!
int total = sizeof ( r ) ;
for ( auto m = r . transaction . mutations . begin ( ) ; m ! = r . transaction . mutations . end ( ) ; + + m )
2018-11-03 03:52:34 +08:00
total + = m - > expectedSize ( ) + CLIENT_KNOBS - > PROXY_COMMIT_OVERHEAD_BYTES ;
2017-05-26 04:48:44 +08:00
for ( auto i = r . transaction . read_conflict_ranges . begin ( ) ; i ! = r . transaction . read_conflict_ranges . end ( ) ; + + i )
total + = i - > expectedSize ( ) ;
for ( auto i = r . transaction . write_conflict_ranges . begin ( ) ; i ! = r . transaction . write_conflict_ranges . end ( ) ; + + i )
total + = i - > expectedSize ( ) ;
return total ;
}
struct GetReadVersionReply {
Version version ;
bool locked ;
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , version , locked ) ;
2017-05-26 04:48:44 +08:00
}
} ;
2018-12-01 02:46:04 +08:00
struct GetReadVersionRequest : TimedRequest {
2017-05-26 04:48:44 +08:00
enum {
PRIORITY_SYSTEM_IMMEDIATE = 15 < < 24 , // Highest possible priority, always executed even if writes are otherwise blocked
PRIORITY_DEFAULT = 8 < < 24 ,
PRIORITY_BATCH = 1 < < 24
} ;
enum {
FLAG_CAUSAL_READ_RISKY = 1 ,
FLAG_PRIORITY_MASK = PRIORITY_SYSTEM_IMMEDIATE ,
} ;
uint32_t transactionCount ;
uint32_t flags ;
Optional < UID > debugID ;
ReplyPromise < GetReadVersionReply > reply ;
GetReadVersionRequest ( ) : transactionCount ( 1 ) , flags ( PRIORITY_DEFAULT ) { }
GetReadVersionRequest ( uint32_t transactionCount , uint32_t flags , Optional < UID > debugID = Optional < UID > ( ) ) : transactionCount ( transactionCount ) , flags ( flags ) , debugID ( debugID ) { }
int priority ( ) const { return flags & FLAG_PRIORITY_MASK ; }
bool operator < ( GetReadVersionRequest const & rhs ) const { return priority ( ) < rhs . priority ( ) ; }
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , transactionCount , flags , debugID , reply ) ;
2017-05-26 04:48:44 +08:00
}
} ;
2017-12-10 08:10:22 +08:00
struct GetKeyServerLocationsReply {
2017-12-16 12:13:44 +08:00
Arena arena ;
2017-12-10 08:10:22 +08:00
vector < pair < KeyRangeRef , vector < StorageServerInterface > > > results ;
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , results , arena ) ;
2017-12-10 08:10:22 +08:00
}
} ;
struct GetKeyServerLocationsRequest {
Arena arena ;
2017-12-16 12:13:44 +08:00
KeyRef begin ;
Optional < KeyRef > end ;
2017-12-10 08:10:22 +08:00
int limit ;
2017-12-16 12:13:44 +08:00
bool reverse ;
2017-12-10 08:10:22 +08:00
ReplyPromise < GetKeyServerLocationsReply > reply ;
2017-12-16 12:13:44 +08:00
GetKeyServerLocationsRequest ( ) : limit ( 0 ) , reverse ( false ) { }
GetKeyServerLocationsRequest ( KeyRef const & begin , Optional < KeyRef > const & end , int limit , bool reverse , Arena const & arena ) : begin ( begin ) , end ( end ) , limit ( limit ) , reverse ( reverse ) , arena ( arena ) { }
2017-12-10 08:10:22 +08:00
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , begin , end , limit , reverse , reply , arena ) ;
2017-12-10 08:10:22 +08:00
}
} ;
2017-05-26 04:48:44 +08:00
struct GetRawCommittedVersionRequest {
Optional < UID > debugID ;
ReplyPromise < GetReadVersionReply > reply ;
explicit GetRawCommittedVersionRequest ( Optional < UID > const & debugID = Optional < UID > ( ) ) : debugID ( debugID ) { }
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , debugID , reply ) ;
2017-05-26 04:48:44 +08:00
}
} ;
struct GetStorageServerRejoinInfoReply {
Version version ;
Tag tag ;
2018-01-29 03:52:54 +08:00
Optional < Tag > newTag ;
bool newLocality ;
vector < pair < Version , Tag > > history ;
2017-05-26 04:48:44 +08:00
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , version , tag , newTag , newLocality , history ) ;
2017-05-26 04:48:44 +08:00
}
} ;
struct GetStorageServerRejoinInfoRequest {
UID id ;
2017-08-04 07:16:36 +08:00
Optional < Value > dcId ;
2017-05-26 04:48:44 +08:00
ReplyPromise < GetStorageServerRejoinInfoReply > reply ;
GetStorageServerRejoinInfoRequest ( ) { }
2017-08-04 07:16:36 +08:00
explicit GetStorageServerRejoinInfoRequest ( UID const & id , Optional < Value > const & dcId ) : id ( id ) , dcId ( dcId ) { }
2017-05-26 04:48:44 +08:00
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , id , dcId , reply ) ;
2017-05-26 04:48:44 +08:00
}
} ;
struct TxnStateRequest {
Arena arena ;
VectorRef < KeyValueRef > data ;
Sequence sequence ;
bool last ;
ReplyPromise < Void > reply ;
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , data , sequence , last , reply , arena ) ;
2017-05-26 04:48:44 +08:00
}
} ;
2019-02-01 05:25:57 +08:00
struct GetHealthMetricsRequest
{
ReplyPromise < struct GetHealthMetricsReply > reply ;
2019-02-24 02:13:43 +08:00
bool detailed ;
GetHealthMetricsRequest ( bool detailed = false ) : detailed ( detailed ) { }
2019-02-01 05:25:57 +08:00
template < class Ar >
void serialize ( Ar & ar )
{
2019-02-24 02:13:43 +08:00
serializer ( ar , reply , detailed ) ;
2019-02-01 05:25:57 +08:00
}
} ;
struct GetHealthMetricsReply
{
2019-02-24 02:13:43 +08:00
Standalone < StringRef > serialized ;
2019-02-01 05:25:57 +08:00
HealthMetrics healthMetrics ;
2019-02-24 02:13:43 +08:00
explicit GetHealthMetricsReply ( HealthMetrics healthMetrics = HealthMetrics ( ) ) :
healthMetrics ( healthMetrics )
2019-02-01 05:25:57 +08:00
{
2019-02-24 02:13:43 +08:00
update ( healthMetrics , true , true ) ;
2019-02-01 05:25:57 +08:00
}
2019-03-03 00:17:20 +08:00
void update ( const HealthMetrics & healthMetrics , bool detailedInput , bool detailedOutput )
2019-02-01 05:25:57 +08:00
{
2019-02-24 02:13:43 +08:00
this - > healthMetrics . update ( healthMetrics , detailedInput , detailedOutput ) ;
2019-02-02 03:45:47 +08:00
BinaryWriter bw ( IncludeVersion ( ) ) ;
2019-02-24 02:13:43 +08:00
bw < < this - > healthMetrics ;
2019-02-01 05:25:57 +08:00
serialized = Standalone < StringRef > ( bw . toStringRef ( ) ) ;
}
template < class Ar >
2019-02-24 02:13:43 +08:00
void serialize ( Ar & ar ) {
2019-02-01 05:25:57 +08:00
serializer ( ar , serialized ) ;
2019-02-24 02:13:43 +08:00
if ( ar . isDeserializing ) {
BinaryReader br ( serialized , IncludeVersion ( ) ) ;
br > > healthMetrics ;
}
2019-02-01 05:25:57 +08:00
}
} ;
2017-05-26 04:48:44 +08:00
# endif