Forsøkt å fikse hengeproblemet.
Jeg tror grunnen til at programmet henger iblant er at det finnes flere åpne sesjoner, og at en annen sesjon har låst noe den aktive sesjonen vil bruke. De fleste menyene som ikke gjorde noen endringer lukket ikke sesjonen sin, og selv de som gjorde endringer lukket sesjonen bare hvis de ble fullført, ikke hvis de ble avbrutt. Jeg har flyttet all åpning og lukking av sesjoner til funksjonen Menu.execute, og lagt til egenskapen Menu.uses_db. For menyer som har denne egenskapen satt til True lages det en sesjon i begynnelsen av execute, og den lukkes før execute returnerer (lukkingen er beskyttet av en finally). Tips for debugging av denne typen problemer (dersom de vedvarer): SELECT * FROM pg_stat_activity; SELECT * FROM pg_locks;
This commit is contained in:
parent
945e6529f5
commit
a0ac2bd633
|
@ -22,7 +22,7 @@ class Menu():
|
||||||
def __init__(self, name, items=[], prompt='> ',
|
def __init__(self, name, items=[], prompt='> ',
|
||||||
return_index=True,
|
return_index=True,
|
||||||
exit_msg=None, exit_confirm_msg=None, exit_disallowed_msg=None,
|
exit_msg=None, exit_confirm_msg=None, exit_disallowed_msg=None,
|
||||||
help_text=None):
|
help_text=None, uses_db=False):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.items = items
|
self.items = items
|
||||||
self.prompt = prompt
|
self.prompt = prompt
|
||||||
|
@ -33,6 +33,7 @@ class Menu():
|
||||||
self.help_text = help_text
|
self.help_text = help_text
|
||||||
self.context = None
|
self.context = None
|
||||||
self.header_format = '[%s]'
|
self.header_format = '[%s]'
|
||||||
|
self.uses_db = uses_db
|
||||||
|
|
||||||
def exit_menu(self):
|
def exit_menu(self):
|
||||||
if self.exit_disallowed_msg != None:
|
if self.exit_disallowed_msg != None:
|
||||||
|
@ -321,10 +322,18 @@ product name or barcode.
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.set_context(None)
|
self.set_context(None)
|
||||||
try:
|
try:
|
||||||
|
if self.uses_db:
|
||||||
|
self.session = Session()
|
||||||
|
else:
|
||||||
|
self.session = None
|
||||||
return self._execute()
|
return self._execute()
|
||||||
except ExitMenu:
|
except ExitMenu:
|
||||||
self.at_exit()
|
self.at_exit()
|
||||||
return None
|
return None
|
||||||
|
finally:
|
||||||
|
if self.session != None:
|
||||||
|
self.session.close()
|
||||||
|
self.session = None
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
while True:
|
while True:
|
||||||
|
@ -404,11 +413,11 @@ class ConfirmMenu(Menu):
|
||||||
|
|
||||||
class TransferMenu(Menu):
|
class TransferMenu(Menu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Transfer credit between users')
|
Menu.__init__(self, 'Transfer credit between users',
|
||||||
|
uses_db=True)
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
self.session = Session()
|
|
||||||
amount = self.input_int('Transfer amount> ', (1,100000))
|
amount = self.input_int('Transfer amount> ', (1,100000))
|
||||||
self.set_context('Transfering %d kr' % amount, display=False)
|
self.set_context('Transfering %d kr' % amount, display=False)
|
||||||
user1 = self.input_user('From user> ')
|
user1 = self.input_user('From user> ')
|
||||||
|
@ -431,17 +440,15 @@ class TransferMenu(Menu):
|
||||||
print 'User %s\'s credit is now %d kr' % (user2, user2.credit)
|
print 'User %s\'s credit is now %d kr' % (user2, user2.credit)
|
||||||
except sqlalchemy.exc.SQLAlchemyError, e:
|
except sqlalchemy.exc.SQLAlchemyError, e:
|
||||||
print 'Could not perform transfer: %s' % e
|
print 'Could not perform transfer: %s' % e
|
||||||
self.session.close()
|
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
|
|
||||||
class AddUserMenu(Menu):
|
class AddUserMenu(Menu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Add user')
|
Menu.__init__(self, 'Add user', uses_db=True)
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
self.session = Session()
|
|
||||||
username = self.input_str('Username (should be same as PVV username)> ', User.name_re, (1,10))
|
username = self.input_str('Username (should be same as PVV username)> ', User.name_re, (1,10))
|
||||||
cardnum = self.input_str('Card number (optional)> ', User.card_re, (0,10))
|
cardnum = self.input_str('Card number (optional)> ', User.card_re, (0,10))
|
||||||
user = User(username, cardnum)
|
user = User(username, cardnum)
|
||||||
|
@ -451,13 +458,12 @@ class AddUserMenu(Menu):
|
||||||
print 'User %s stored' % username
|
print 'User %s stored' % username
|
||||||
except sqlalchemy.exc.IntegrityError, e:
|
except sqlalchemy.exc.IntegrityError, e:
|
||||||
print 'Could not store user %s: %s' % (username,e)
|
print 'Could not store user %s: %s' % (username,e)
|
||||||
self.session.close()
|
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
|
|
||||||
class EditUserMenu(Menu):
|
class EditUserMenu(Menu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Edit user')
|
Menu.__init__(self, 'Edit user', uses_db=True)
|
||||||
self.help_text = '''
|
self.help_text = '''
|
||||||
The only editable part of a user is its card number.
|
The only editable part of a user is its card number.
|
||||||
|
|
||||||
|
@ -467,7 +473,6 @@ user (write an empty line to remove the card number).
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
self.session = Session()
|
|
||||||
user = self.input_user('User> ')
|
user = self.input_user('User> ')
|
||||||
self.printc('Editing user %s' % user.name)
|
self.printc('Editing user %s' % user.name)
|
||||||
card_str = '"%s"' % user.card
|
card_str = '"%s"' % user.card
|
||||||
|
@ -481,16 +486,14 @@ user (write an empty line to remove the card number).
|
||||||
print 'User %s stored' % user.name
|
print 'User %s stored' % user.name
|
||||||
except sqlalchemy.exc.SQLAlchemyError, e:
|
except sqlalchemy.exc.SQLAlchemyError, e:
|
||||||
print 'Could not store user %s: %s' % (user.name,e)
|
print 'Could not store user %s: %s' % (user.name,e)
|
||||||
self.session.close()
|
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
|
|
||||||
class AddProductMenu(Menu):
|
class AddProductMenu(Menu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Add product')
|
Menu.__init__(self, 'Add product', uses_db=True)
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.session = Session()
|
|
||||||
self.print_header()
|
self.print_header()
|
||||||
bar_code = self.input_str('Bar code> ', Product.bar_code_re, (8,13))
|
bar_code = self.input_str('Bar code> ', Product.bar_code_re, (8,13))
|
||||||
name = self.input_str('Name> ', Product.name_re, (1,30))
|
name = self.input_str('Name> ', Product.name_re, (1,30))
|
||||||
|
@ -502,17 +505,15 @@ class AddProductMenu(Menu):
|
||||||
print 'Product %s stored' % name
|
print 'Product %s stored' % name
|
||||||
except sqlalchemy.exc.SQLAlchemyError, e:
|
except sqlalchemy.exc.SQLAlchemyError, e:
|
||||||
print 'Could not store product %s: %s' % (name,e)
|
print 'Could not store product %s: %s' % (name,e)
|
||||||
self.session.close()
|
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
|
|
||||||
class EditProductMenu(Menu):
|
class EditProductMenu(Menu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Edit product')
|
Menu.__init__(self, 'Edit product', uses_db=True)
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
self.session = Session()
|
|
||||||
product = self.input_product('Product> ')
|
product = self.input_product('Product> ')
|
||||||
self.printc('Editing product %s' % product.name)
|
self.printc('Editing product %s' % product.name)
|
||||||
while True:
|
while True:
|
||||||
|
@ -531,7 +532,6 @@ class EditProductMenu(Menu):
|
||||||
print 'Product %s stored' % product.name
|
print 'Product %s stored' % product.name
|
||||||
except sqlalchemy.exc.SQLAlchemyError, e:
|
except sqlalchemy.exc.SQLAlchemyError, e:
|
||||||
print 'Could not store product %s: %s' % (product.name, e)
|
print 'Could not store product %s: %s' % (product.name, e)
|
||||||
self.session.close()
|
|
||||||
self.pause()
|
self.pause()
|
||||||
return
|
return
|
||||||
elif what == None:
|
elif what == None:
|
||||||
|
@ -543,10 +543,9 @@ class EditProductMenu(Menu):
|
||||||
|
|
||||||
class ShowUserMenu(Menu):
|
class ShowUserMenu(Menu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Show user')
|
Menu.__init__(self, 'Show user', uses_db=True)
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.session = Session()
|
|
||||||
self.print_header()
|
self.print_header()
|
||||||
user = self.input_user('User name or card number> ')
|
user = self.input_user('User name or card number> ')
|
||||||
print 'User name: %s' % user.name
|
print 'User name: %s' % user.name
|
||||||
|
@ -582,11 +581,10 @@ class ShowUserMenu(Menu):
|
||||||
|
|
||||||
class UserListMenu(Menu):
|
class UserListMenu(Menu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'User list')
|
Menu.__init__(self, 'User list', uses_db=True)
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
self.session = Session()
|
|
||||||
user_list = self.session.query(User).all()
|
user_list = self.session.query(User).all()
|
||||||
total_credit = self.session.query(sqlalchemy.func.sum(User.credit)).first()[0]
|
total_credit = self.session.query(sqlalchemy.func.sum(User.credit)).first()[0]
|
||||||
|
|
||||||
|
@ -598,14 +596,12 @@ class UserListMenu(Menu):
|
||||||
print line_format % (user.name, user.credit)
|
print line_format % (user.name, user.credit)
|
||||||
print hline
|
print hline
|
||||||
print line_format % ('total credit', total_credit)
|
print line_format % ('total credit', total_credit)
|
||||||
|
|
||||||
self.session.close()
|
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
|
|
||||||
class BuyMenu(Menu):
|
class BuyMenu(Menu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Buy')
|
Menu.__init__(self, 'Buy', uses_db=True)
|
||||||
self.help_text = '''
|
self.help_text = '''
|
||||||
Each purchase may contain one or more products and one or more buyers.
|
Each purchase may contain one or more products and one or more buyers.
|
||||||
|
|
||||||
|
@ -618,7 +614,6 @@ When finished, write an empty line to confirm the purchase.
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
self.session = Session()
|
|
||||||
self.purchase = Purchase()
|
self.purchase = Purchase()
|
||||||
self.exit_confirm_msg=None
|
self.exit_confirm_msg=None
|
||||||
while True:
|
while True:
|
||||||
|
@ -659,7 +654,6 @@ When finished, write an empty line to confirm the purchase.
|
||||||
self.print_purchase()
|
self.print_purchase()
|
||||||
for t in self.purchase.transactions:
|
for t in self.purchase.transactions:
|
||||||
print 'User %s\'s credit is now %d kr' % (t.user.name, t.user.credit)
|
print 'User %s\'s credit is now %d kr' % (t.user.name, t.user.credit)
|
||||||
self.session.close()
|
|
||||||
self.pause()
|
self.pause()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -698,11 +692,10 @@ When finished, write an empty line to confirm the purchase.
|
||||||
|
|
||||||
class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combined to one
|
class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combined to one
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Adjust credit')
|
Menu.__init__(self, 'Adjust credit', uses_db=True)
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
self.session = Session()
|
|
||||||
user = self.input_user('User> ')
|
user = self.input_user('User> ')
|
||||||
print 'User %s\'s credit is %d kr' % (user.name, user.credit)
|
print 'User %s\'s credit is %d kr' % (user.name, user.credit)
|
||||||
self.set_context('Adjusting credit for user %s' % user.name, display=False)
|
self.set_context('Adjusting credit for user %s' % user.name, display=False)
|
||||||
|
@ -718,24 +711,21 @@ class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combine
|
||||||
print 'User %s\'s credit is now %d kr' % (user.name, user.credit)
|
print 'User %s\'s credit is now %d kr' % (user.name, user.credit)
|
||||||
except sqlalchemy.exc.SQLAlchemyError, e:
|
except sqlalchemy.exc.SQLAlchemyError, e:
|
||||||
print 'Could not store transaction: %s' % e
|
print 'Could not store transaction: %s' % e
|
||||||
self.session.close()
|
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
|
|
||||||
class ProductListMenu(Menu):
|
class ProductListMenu(Menu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Product list')
|
Menu.__init__(self, 'Product list', uses_db=True)
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
self.session = Session()
|
|
||||||
product_list = self.session.query(Product).all()
|
product_list = self.session.query(Product).all()
|
||||||
line_format = '%-30s | %6s | %-15s'
|
line_format = '%-30s | %6s | %-15s'
|
||||||
print line_format % ('name', 'price', 'bar code')
|
print line_format % ('name', 'price', 'bar code')
|
||||||
print '---------------------------------------------------------'
|
print '---------------------------------------------------------'
|
||||||
for p in product_list:
|
for p in product_list:
|
||||||
print line_format % (p.name, p.price, p.bar_code)
|
print line_format % (p.name, p.price, p.bar_code)
|
||||||
self.session.close()
|
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue