rollbacker.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. '''This file is part of AToMPM - A Tool for Multi-Paradigm Modelling
  2. Copyright 2011 by the AToMPM team and licensed under the LGPL
  3. See COPYING.lesser and README.md in the root of this project for full details'''
  4. #import pickle, os
  5. from ..util.infinity import INFINITY
  6. from .iterator import Iterator
  7. from ..tcore.messages import TransformationException
  8. class Rollbacker(Iterator):
  9. '''
  10. Provides back-tracking capacity.
  11. '''
  12. def __init__(self, condition, max_iterations=INFINITY):
  13. '''
  14. Selects one match from the packet.
  15. @param condition: The pre-condition pattern.
  16. @param max_iterations: The maximum number of times to select.
  17. By default, this is +INFINITY.
  18. '''
  19. super(Rollbacker, self).__init__(condition, max_iterations)
  20. self.checkpoints = [] # Stack of file names
  21. def packet_in(self, packet):
  22. self.exception = None
  23. self.is_success = False
  24. try:
  25. self.establish(packet)
  26. self.is_success = True
  27. except Exception as e:
  28. self.is_success = False
  29. self.exception = TransformationException(e)
  30. self.exception.packet = packet
  31. self.exception.transformation_unit = self
  32. finally:
  33. self.iterations = 1
  34. return packet
  35. def next_in(self, packet):
  36. self.exception = None
  37. self.is_success = False
  38. if self.iterations < self.max_iterations:
  39. # If came from the same scope as the rollbacker, then just pass it over
  40. if packet.current in packet.match_sets:
  41. self.iterations += 1
  42. self.is_success = True
  43. return packet
  44. else:
  45. try:
  46. packet.set_state(self.restore())
  47. self.is_success = True
  48. except Exception as e:
  49. self.is_success = False
  50. self.excepion = TransformationException(e)
  51. self.exception.packet = packet
  52. self.exception.transformation_unit = self
  53. finally:
  54. return packet
  55. else: # self.iterations == self.max_iterations
  56. try:
  57. packet = self.restore()
  58. self.is_success = True
  59. except:
  60. self.is_success = False
  61. finally:
  62. return packet
  63. def establish(self, packet):
  64. # fileName = '%d.tc_state.%d' % (self._id, len(self.checkpoints))
  65. # with open(fileName, 'w') as storage:
  66. # pickle.dump(packet, storage)
  67. # self.checkpoints.append(fileName)
  68. self.checkpoints.append(packet.copy_state(self.condition))
  69. def restore(self):
  70. # with open(self.checkpoints[-1], 'r') as storage:
  71. # packet = pickle.load(storage)
  72. # return packet
  73. # os.remove(self.checkpoints[-1])
  74. if len(self.checkpoints) > 0:
  75. return self.checkpoints.pop()
  76. raise Exception('There are no checkpoints to restore')
  77. def discard(self):
  78. # os.remove(self.checkpoints[-1])
  79. if len(self.checkpoints) > 0:
  80. del self.checkpoints[-1]
  81. raise Exception('There are no checkpoints to discard')
  82. def discard_all(self):
  83. # for fn in self.checkpoints:
  84. # os.remove(fn)
  85. self.checkpoints = []