compact only one view per shared index file
[mygpo.git] / mygpo / maintenance / management / commands / compact-couchdb.py
blob68b015e7d3f3bc053238663348e38fe097e4d7dd
1 import sys
2 from datetime import datetime
3 from time import sleep
5 from couchdbkit import Database
6 from django.core.management.base import BaseCommand
7 from django.conf import settings
9 from mygpo.decorators import repeat_on_conflict
10 from mygpo.core.models import SanitizingRule
11 from mygpo.utils import progress
15 class Command(BaseCommand):
16 """
17 Compacts the database and all views, and measures the required time
18 """
20 @staticmethod
21 def get_design_docs(db):
22 prefix = '_design/'
23 prefix_len = len(prefix)
25 for ddoc in db.view('_all_docs', startkey='_design/', endkey='_design0'):
26 yield ddoc['key'][prefix_len:]
29 def handle(self, *args, **options):
31 db_url = settings.COUCHDB_DATABASES[0][1]
32 db = Database(db_url)
34 print 'Compacting Database ... ',
35 sys.stdout.flush()
36 compact_db = lambda: db.compact()
37 db_is_compacting = lambda: db.info()['compact_running']
38 duration = self.compact_wait(compact_db, db_is_compacting)
39 print duration
41 # Only compact once if multiple views share one index file
42 ddocs = {}
43 for ddoc in self.get_design_docs(db):
44 sig = db.res.get('/_design/%s/_info' % ddoc).json_body['view_index']['signature']
45 ddocs[sig] = ddoc
47 for design_doc in ddocs.values():
48 print 'Compacting %s ...' % design_doc,
49 sys.stdout.flush
50 compact_view = lambda: db.compact('%s' % design_doc)
51 view_is_compacting = lambda: db.res.get('/_design/%s/_info' % design_doc).json_body['view_index']['compact_running']
52 duration = self.compact_wait(compact_view, view_is_compacting)
53 print duration
56 @staticmethod
57 def compact_wait(compact, is_compacting, sleep_time=1, inc_factor = 2):
59 start = datetime.utcnow()
61 while True:
62 try:
63 compact()
64 break
65 except Exception, e:
66 sleep(100)
67 print >> sys.stderr, e
69 while True:
70 try:
71 is_comp = is_compacting()
72 if is_comp:
73 sleep(sleep_time)
74 sleep_time *= inc_factor
75 else:
76 break
78 except Exception, e:
79 sleep(100)
80 print >> sys.stderr, e
82 end = datetime.utcnow()
84 return end - start