SOLR-4661: Admin UI Replication details now correctly displays the current replicable generation/version of the master

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1469073 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Chris M. Hostetter 2013-04-17 21:13:20 +00:00
parent 9c56dccf19
commit ad47f73895
7 changed files with 120 additions and 41 deletions

View File

@ -224,6 +224,9 @@ Bug Fixes
code is not something Solr itself returned -- eg: from the Servlet Container, code is not something Solr itself returned -- eg: from the Servlet Container,
or an intermediate HTTP Proxy (hossman) or an intermediate HTTP Proxy (hossman)
* SOLR-4661: Admin UI Replication details now correctly displays the current
replicable generation/version of the master. (hossman)
Optimizations Optimizations
---------------------- ----------------------

View File

@ -78,7 +78,7 @@ import org.slf4j.LoggerFactory;
/** /**
* <p> A Handler which provides a REST API for replication and serves replication requests from Slaves. <p/> </p> * <p> A Handler which provides a REST API for replication and serves replication requests from Slaves. <p/> </p>
* <p>When running on the master, it provides the following commands <ol> <li>Get the current replicatable index version * <p>When running on the master, it provides the following commands <ol> <li>Get the current replicable index version
* (command=indexversion)</li> <li>Get the list of files for a given index version * (command=indexversion)</li> <li>Get the list of files for a given index version
* (command=filelist&amp;indexversion=&lt;VERSION&gt;)</li> <li>Get full or a part (chunk) of a given index or a config * (command=filelist&amp;indexversion=&lt;VERSION&gt;)</li> <li>Get full or a part (chunk) of a given index or a config
* file (command=filecontent&amp;file=&lt;FILE_NAME&gt;) You can optionally specify an offset and length to get that * file (command=filecontent&amp;file=&lt;FILE_NAME&gt;) You can optionally specify an offset and length to get that
@ -96,6 +96,38 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
private static final Logger LOG = LoggerFactory.getLogger(ReplicationHandler.class.getName()); private static final Logger LOG = LoggerFactory.getLogger(ReplicationHandler.class.getName());
SolrCore core; SolrCore core;
private static final class CommitVersionInfo {
public final long version;
public final long generation;
private CommitVersionInfo(long g, long v) {
generation = g;
version = v;
}
/**
* builds a CommitVersionInfo data for the specified IndexCommit.
* Will never be null, ut version and generation may be zero if
* there are problems extracting them from the commit data
*/
public static CommitVersionInfo build(IndexCommit commit) {
long generation = commit.getGeneration();
long version = 0;
try {
final Map<String,String> commitData = commit.getUserData();
String commitTime = commitData.get(SolrIndexWriter.COMMIT_TIME_MSEC_KEY);
if (commitTime != null) {
try {
version = Long.parseLong(commitTime);
} catch (NumberFormatException e) {
LOG.warn("Version in commitData was not formated correctly: " + commitTime, e);
}
}
} catch (IOException e) {
LOG.warn("Unable to get version from commitData, commit: " + commit, e);
}
return new CommitVersionInfo(generation, version);
}
}
private SnapPuller snapPuller; private SnapPuller snapPuller;
private ReentrantLock snapPullLock = new ReentrantLock(); private ReentrantLock snapPullLock = new ReentrantLock();
@ -501,23 +533,20 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
return "$URL$"; return "$URL$";
} }
private long[] getIndexVersion() { /**
long version[] = new long[2]; * returns the CommitVersionInfo for the current searcher, or null on error.
*/
private CommitVersionInfo getIndexVersion() {
CommitVersionInfo v = null;
RefCounted<SolrIndexSearcher> searcher = core.getSearcher(); RefCounted<SolrIndexSearcher> searcher = core.getSearcher();
try { try {
final IndexCommit commit = searcher.get().getIndexReader().getIndexCommit(); v = CommitVersionInfo.build(searcher.get().getIndexReader().getIndexCommit());
final Map<String,String> commitData = commit.getUserData();
String commitTime = commitData.get(SolrIndexWriter.COMMIT_TIME_MSEC_KEY);
if (commitTime != null) {
version[0] = Long.parseLong(commitTime);
}
version[1] = commit.getGeneration();
} catch (IOException e) { } catch (IOException e) {
LOG.warn("Unable to get index version : ", e); LOG.warn("Unable to get index commit: ", e);
} finally { } finally {
searcher.decref(); searcher.decref();
} }
return version; return v;
} }
@Override @Override
@ -526,9 +555,9 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
NamedList list = super.getStatistics(); NamedList list = super.getStatistics();
if (core != null) { if (core != null) {
list.add("indexSize", NumberUtils.readableSize(getIndexSize())); list.add("indexSize", NumberUtils.readableSize(getIndexSize()));
long[] versionGen = getIndexVersion(); CommitVersionInfo vInfo = getIndexVersion();
list.add("indexVersion", versionGen[0]); list.add("indexVersion", null == vInfo ? 0 : vInfo.version);
list.add(GENERATION, versionGen[1]); list.add(GENERATION, null == vInfo ? 0 : vInfo.generation);
list.add("indexPath", core.getIndexDir()); list.add("indexPath", core.getIndexDir());
list.add("isMaster", String.valueOf(isMaster)); list.add("isMaster", String.valueOf(isMaster));
@ -582,9 +611,9 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
details.add(CMD_SHOW_COMMITS, getCommits()); details.add(CMD_SHOW_COMMITS, getCommits());
details.add("isMaster", String.valueOf(isMaster)); details.add("isMaster", String.valueOf(isMaster));
details.add("isSlave", String.valueOf(isSlave)); details.add("isSlave", String.valueOf(isSlave));
long[] versionAndGeneration = getIndexVersion(); CommitVersionInfo vInfo = getIndexVersion();
details.add("indexVersion", versionAndGeneration[0]); details.add("indexVersion", null == vInfo ? 0 : vInfo.version);
details.add(GENERATION, versionAndGeneration[1]); details.add(GENERATION, null == vInfo ? 0 : vInfo.generation);
IndexCommit commit = indexCommitPoint; // make a copy so it won't change IndexCommit commit = indexCommitPoint; // make a copy so it won't change
@ -595,7 +624,9 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
} }
if (isMaster && commit != null) { if (isMaster && commit != null) {
master.add("replicatableGeneration", commit.getGeneration()); CommitVersionInfo repCommitInfo = CommitVersionInfo.build(commit);
master.add("replicableVersion", repCommitInfo.version);
master.add("replicableGeneration", repCommitInfo.generation);
} }
SnapPuller snapPuller = tempSnapPuller; SnapPuller snapPuller = tempSnapPuller;

View File

@ -283,6 +283,7 @@
#content #replication #details table #content #replication #details table
{ {
margin-left: 20px;
border-collapse: collapse; border-collapse: collapse;
} }
@ -339,6 +340,7 @@
{ {
padding-right: 10px; padding-right: 10px;
text-align: right; text-align: right;
white-space: nowrap;
} }
#content #replication #details table tbody .size #content #replication #details table tbody .size

View File

@ -256,7 +256,8 @@ sammy.get
var is_slave = 'undefined' !== typeof( data.slave ); var is_slave = 'undefined' !== typeof( data.slave );
var headline = $( 'h2 span', this ); var headline = $( 'h2 span', this );
var details_element = $( '#details', this ); var details_element = $( '#details', this );
var current_type_element = $( ( is_slave ? '.slave' : '.master' ), this ); var current_type_element = $( ( is_slave ? '.slave' : '.masterSearch' ), this );
var master_data = is_slave ? data.slave.masterDetails : data;
if( is_slave ) if( is_slave )
{ {
@ -275,6 +276,7 @@ sammy.get
.html( headline.html() + ' (Master)' ); .html( headline.html() + ' (Master)' );
} }
// the currently searchable commit regardless of type
$( '.version div', current_type_element ) $( '.version div', current_type_element )
.html( data.indexVersion ); .html( data.indexVersion );
$( '.generation div', current_type_element ) $( '.generation div', current_type_element )
@ -282,9 +284,18 @@ sammy.get
$( '.size div', current_type_element ) $( '.size div', current_type_element )
.html( data.indexSize ); .html( data.indexSize );
// what's replicable on the master
var master_element = $( '.master', details_element );
$( '.version div', master_element )
.html( master_data.master.replicableVersion || '-' );
$( '.generation div', master_element )
.html( master_data.master.replicableGeneration || '-' );
$( '.size div', master_element )
.html( "-" );
if( is_slave ) if( is_slave )
{ {
var master_element = $( '.master', details_element ); var master_element = $( '.masterSearch', details_element );
$( '.version div', master_element ) $( '.version div', master_element )
.html( data.slave.masterDetails.indexVersion ); .html( data.slave.masterDetails.indexVersion );
$( '.generation div', master_element ) $( '.generation div', master_element )
@ -292,7 +303,8 @@ sammy.get
$( '.size div', master_element ) $( '.size div', master_element )
.html( data.slave.masterDetails.indexSize ); .html( data.slave.masterDetails.indexSize );
if( data.indexVersion !== data.slave.masterDetails.indexVersion ) // warnings if slave version|gen doesn't match what's replicable
if( data.indexVersion !== master_data.master.replicableVersion )
{ {
$( '.version', details_element ) $( '.version', details_element )
.addClass( 'diff' ); .addClass( 'diff' );
@ -303,7 +315,7 @@ sammy.get
.removeClass( 'diff' ); .removeClass( 'diff' );
} }
if( data.generation !== data.slave.masterDetails.generation ) if( data.generation !== master_data.master.replicableGeneration )
{ {
$( '.generation', details_element ) $( '.generation', details_element )
.addClass( 'diff' ); .addClass( 'diff' );

View File

@ -246,8 +246,10 @@ var replication_fetch_status = function()
} }
var details_element = $( '#details', replication_element ); var details_element = $( '#details', replication_element );
var current_type_element = $( ( is_slave ? '.slave' : '.master' ), details_element ); var current_type_element = $( ( is_slave ? '.slave' : '.masterSearch' ), details_element );
var master_data = is_slave ? data.slave.masterDetails : data;
// the currently searchable commit regardless of type
$( '.version div', current_type_element ) $( '.version div', current_type_element )
.html( data.indexVersion ); .html( data.indexVersion );
$( '.generation div', current_type_element ) $( '.generation div', current_type_element )
@ -255,17 +257,28 @@ var replication_fetch_status = function()
$( '.size div', current_type_element ) $( '.size div', current_type_element )
.html( data.indexSize ); .html( data.indexSize );
if( is_slave ) // what's replicable on the master
{
var master_element = $( '.master', details_element ); var master_element = $( '.master', details_element );
$( '.version div', master_element ) $( '.version div', master_element )
.html( data.slave.masterDetails.indexVersion ); .html( master_data.master.replicableVersion || '-' );
$( '.generation div', master_element ) $( '.generation div', master_element )
.html( data.slave.masterDetails.generation ); .html( master_data.master.replicableGeneration || '-' );
$( '.size div', master_element ) $( '.size div', master_element )
.html( data.slave.masterDetails.indexSize ); .html( "-" );
if( data.indexVersion !== data.slave.masterDetails.indexVersion ) if( is_slave )
{
// what's searchable on the master
var master_searchable = $( '.masterSearch', details_element );
$( '.version div', master_searchable )
.html( master_data.indexVersion );
$( '.generation div', master_searchable )
.html( master_data.generation );
$( '.size div', master_searchable )
.html( master_data.indexSize );
// warnings if slave version|gen doesn't match what's replicable
if( data.indexVersion !== master_data.master.replicableVersion )
{ {
$( '.version', details_element ) $( '.version', details_element )
.addClass( 'diff' ); .addClass( 'diff' );
@ -276,7 +289,7 @@ var replication_fetch_status = function()
.removeClass( 'diff' ); .removeClass( 'diff' );
} }
if( data.generation !== data.slave.masterDetails.generation ) if( data.generation !== master_data.master.replicableGeneration )
{ {
$( '.generation', details_element ) $( '.generation', details_element )
.addClass( 'diff' ); .addClass( 'diff' );

View File

@ -103,9 +103,18 @@ limitations under the License.
</thead> </thead>
<tbody> <tbody>
<tr class="masterSearch">
<th>Master (Searching)</th>
<td class="version"><div>x</div></td>
<td class="generation"><div>y</div></td>
<td class="size"><div>z</div></td>
</tr>
<tr class="master"> <tr class="master">
<th>Master:</th> <th>Master (Replicable)</th>
<td class="version"><div>x</div></td> <td class="version"><div>x</div></td>
<td class="generation"><div>y</div></td> <td class="generation"><div>y</div></td>
<td class="size"><div>z</div></td> <td class="size"><div>z</div></td>
@ -114,7 +123,7 @@ limitations under the License.
<tr class="slave slaveOnly"> <tr class="slave slaveOnly">
<th>Slave:</th> <th>Slave (Searching)</th>
<td class="version"><div>a</div></td> <td class="version"><div>a</div></td>
<td class="generation"><div>c</div></td> <td class="generation"><div>c</div></td>
<td class="size"><div>c</div></td> <td class="size"><div>c</div></td>

View File

@ -116,9 +116,18 @@ limitations under the License.
</thead> </thead>
<tbody> <tbody>
<tr class="masterSearch">
<th>Master (Searching)</th>
<td class="version"><div></div></td>
<td class="generation"><div></div></td>
<td class="size"><div></div></td>
</tr>
<tr class="master"> <tr class="master">
<th>Master:</th> <th>Master (Replicable)</th>
<td class="version"><div></div></td> <td class="version"><div></div></td>
<td class="generation"><div></div></td> <td class="generation"><div></div></td>
<td class="size"><div></div></td> <td class="size"><div></div></td>
@ -127,7 +136,7 @@ limitations under the License.
<tr class="slave slaveOnly"> <tr class="slave slaveOnly">
<th>Slave:</th> <th>Slave (Searching)</th>
<td class="version"><div></div></td> <td class="version"><div></div></td>
<td class="generation"><div></div></td> <td class="generation"><div></div></td>
<td class="size"><div></div></td> <td class="size"><div></div></td>