This repository has been archived by the owner on Jan 31, 2018. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[bug 788527] Add indexing to search admin
* add indexing-related celery tasks * add indexing form in admin * add reset form in admin * add record history to admin * add test for index_chunk_test * fix ES test infrastructure to work correctly * updated ES docs
- Loading branch information
Showing
12 changed files
with
417 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# -*- coding: utf-8 -*- | ||
import datetime | ||
from south.db import db | ||
from south.v2 import SchemaMigration | ||
from django.db import models | ||
|
||
|
||
class Migration(SchemaMigration): | ||
|
||
def forwards(self, orm): | ||
# Adding model 'Record' | ||
db.create_table('search_record', ( | ||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), | ||
('batch_id', self.gf('django.db.models.fields.CharField')(max_length=10)), | ||
('name', self.gf('django.db.models.fields.CharField')(max_length=255)), | ||
('creation_time', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), | ||
('start_time', self.gf('django.db.models.fields.DateTimeField')(null=True)), | ||
('end_time', self.gf('django.db.models.fields.DateTimeField')(null=True)), | ||
('status', self.gf('django.db.models.fields.IntegerField')(default=0)), | ||
('message', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), | ||
)) | ||
db.send_create_signal('search', ['Record']) | ||
|
||
|
||
def backwards(self, orm): | ||
# Deleting model 'Record' | ||
db.delete_table('search_record') | ||
|
||
|
||
models = { | ||
'search.record': { | ||
'Meta': {'object_name': 'Record'}, | ||
'batch_id': ('django.db.models.fields.CharField', [], {'max_length': '10'}), | ||
'creation_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), | ||
'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), | ||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
'message': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), | ||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||
'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), | ||
'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}) | ||
} | ||
} | ||
|
||
complete_apps = ['search'] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import datetime | ||
|
||
from django.db import models | ||
|
||
|
||
# Note: This doesn't extend our caching ModelBase because we | ||
# explicitly want the livest data possible and not cached data. | ||
|
||
class Record(models.Model): | ||
"""Indexing record.""" | ||
STATUS_NEW = 0 | ||
STATUS_IN_PROGRESS = 1 | ||
STATUS_FAIL = 2 | ||
STATUS_SUCCESS = 3 | ||
|
||
STATUS_CHOICES = ( | ||
(STATUS_NEW, 'new'), | ||
(STATUS_IN_PROGRESS, 'in progress'), | ||
(STATUS_FAIL, 'done - fail'), | ||
(STATUS_SUCCESS, 'done - success'), | ||
) | ||
|
||
batch_id = models.CharField(max_length=10) | ||
name = models.CharField(max_length=255) | ||
creation_time = models.DateTimeField(auto_now_add=True) | ||
start_time = models.DateTimeField(null=True) | ||
end_time = models.DateTimeField(null=True) | ||
status = models.IntegerField(choices=STATUS_CHOICES, default=STATUS_NEW) | ||
message = models.CharField(max_length=255, blank=True) | ||
|
||
def delta(self): | ||
"""Return the timedelta.""" | ||
if self.start_time and self.end_time: | ||
return self.end_time - self.start_time | ||
return None | ||
|
||
def _complete(self, status, msg='Done'): | ||
self.end_time = datetime.datetime.now() | ||
self.status = status | ||
self.message = msg | ||
|
||
def mark_fail(self, msg): | ||
"""Mark as failed. | ||
:arg msg: the error message it failed with | ||
""" | ||
self._complete(self.STATUS_FAIL, msg) | ||
self.save() | ||
|
||
def mark_success(self, msg='Success'): | ||
"""Mark as succeeded. | ||
:arg msg: success message if any | ||
""" | ||
self._complete(self.STATUS_SUCCESS, msg) | ||
self.save() | ||
|
||
@classmethod | ||
def outstanding(cls): | ||
"""Return queryset of outstanding records.""" | ||
return cls.objects.filter(status__in=[ | ||
cls.STATUS_NEW, cls.STATUS_IN_PROGRESS]) | ||
|
||
def __unicode__(self): | ||
return '%s:%s%s' % (self.batch_id, self.name, self.status) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import datetime | ||
import logging | ||
import sys | ||
|
||
from celery.decorators import task | ||
from multidb.pinning import pin_this_thread, unpin_this_thread | ||
|
||
from fjord.search.index import index_chunk | ||
from fjord.search.models import Record | ||
|
||
|
||
log = logging.getLogger('i.task') | ||
|
||
|
||
@task | ||
def index_chunk_task(index, batch_id, rec_id, chunk): | ||
"""Index a chunk of things. | ||
:arg index: the name of the index to index to | ||
:arg batch_id: the name for the batch this chunk belongs to | ||
:arg rec_id: the id for the record for this task | ||
:arg chunk: a (class, id_list) of things to index | ||
""" | ||
cls, id_list = chunk | ||
|
||
try: | ||
# Pin to master db to avoid replication lag issues and stale | ||
# data. | ||
pin_this_thread() | ||
|
||
# Update record data. | ||
rec = Record.objects.get(pk=rec_id) | ||
rec.start_time = datetime.datetime.now() | ||
rec.message = u'Reindexing into %s' % index | ||
rec.status = Record.STATUS_IN_PROGRESS | ||
rec.save() | ||
|
||
index_chunk(cls, id_list, reraise=True) | ||
|
||
rec.mark_success() | ||
|
||
except Exception: | ||
rec.mark_fail(u'Errored out %s %s' % ( | ||
sys.exc_type, sys.exc_value)) | ||
raise | ||
|
||
finally: | ||
unpin_this_thread() |
Oops, something went wrong.