Exemple #1
0
  def test_find_or_upsert(self):
    class UpsertTest(ModelBase):
      table_name = "upserts"
      attrs = { "name": None, "type": None }

    def insert(ma, name, type):
      return ma.insert_model(UpsertTest(name=name, type=type))

    def upsert(ma, name, type, assign):
      with transaction(ma):
        assign.append(ma.find_or_upsert(UpsertTest, dict(name=name, type=type), comp=dict(name=name), return_status=True))

    with get_model_access() as ma1, get_model_access() as ma2:
      with autocommit(ma1):
        ma1.execute("drop table if exists upserts")
        ma1.execute("create table upserts (id serial not null primary key, name text not null unique, type text not null, created_at timestamptz not null default now(), updated_at timestamptz not null default now());")
        ma1.execute("truncate table upserts")

      # 1) Two transactions: a) create b) upsert a) commit - check that a and b have same id
      # 2) Two transactions: a) create b) upsert a) rollback - check that a and b have differnet ids

      with transaction(ma1):
        mod1 = insert(ma1, "Trey", "person")
        mod2a = []
        thread1 = Thread(target=lambda: upsert(ma2, "Trey", "person", mod2a))
        thread1.start()
        sleep(0.25)
        self.assertTrue(thread1.is_alive())
      thread1.join()
      mod2, mod2_status = mod2a[0]
      self.assertEqual(mod2_status, "duplicate")
      self.assertEqual(mod1.id, mod2.id)

      with transaction(ma1):
        mod3 = insert(ma1, "Julie", "person")
        mod4a = []
        thread2 = Thread(target=lambda: upsert(ma2, "Julie", "person", mod4a))
        thread2.start()
        sleep(0.25)
        self.assertTrue(thread2.is_alive())
        raise RollbackTransaction()
      thread2.join()
      mod4, mod4_status = mod4a[0]
      self.assertEqual(mod4_status, "created")
      self.assertNotEqual(mod3.id, mod4.id)

      mod5a = []
      upsert(ma1, "Trey", "person", mod5a)
      mod5, mod5_status = mod5a[0]
      self.assertEqual(mod5_status, "found")
      self.assertEqual(mod5.id, mod1.id)
Exemple #2
0
  def _start_a_job(self):
    """Either starts a waiting job and returns a 3-tuple of (job, sz_key, future),
    or finds no waiting job and returns a 3-tuple of (None, None, None).
    """
    with transaction(self._model_access):
      (job, sz_key) = self._get_next_job()

      if job is None:
        return (None, None, None)

      job.started_at = utc_now()
      if sz_key:
        sz_key.active_job_id = job.id

      self._update_job(job, sz_key)

    def fxn():
      """Future closure."""
      if job.name not in self._job_handlers:
        raise KeyError("Bad job name")
      self._job_handlers[job.name](job.payload)

    future = self._executor.submit(fxn)

    return (job, sz_key, future)
Exemple #3
0
 def test_autocommit_contextmanager(self):
     da = get_data_access().open(autocommit=False)
     cnst = dict(first_name=rand(), last_name=rand(), age=3)
     with transaction(da):
         with autocommit(da):
             da.insert("people", cnst)
             # Rollback should have no effect
             da.rollback()
     self.assertEqual(da.find("people", cnst).first_name, cnst["first_name"])
     da.delete("people", cnst)
     da.commit()
Exemple #4
0
 def test_transaction_contextmanager(self):
     da1 = get_data_access().open()
     da2 = get_data_access().open()
     da1.autocommit = False
     cnst = dict(first_name=rand(), last_name=rand(), age=3)
     with transaction(da1) as da:
         self.assertIsInstance(da, DataAccess)
     with transaction(da1):
         da1.insert("people", cnst)
     self.assertEqual(da2.find("people", cnst).first_name, cnst["first_name"])
     with transaction(da1):
         da1.delete("people", cnst)
     da1.autocommit = True
     self.assertEqual(da1.count("people"), 11)
     try:
         with transaction(da1):
             da1.insert("people", cnst)
             raise Exception()
     except Exception as ex:
         pass
     finally:
         self.assertIsNone(da1.find("people", cnst))
Exemple #5
0
  def _finished_job(self, job, sz_key, future):
    """Marks the job as complete.

    :param job: the Job instance
    :param sz_key: the SerializationKey instance
    :param future: the Future instance that handled the job
    """
    error_message = exception_to_message(future.exception())
    job.update(completed_at=utc_now(), error_message=error_message)
    if sz_key:
      sz_key.active_job_id = None

    with transaction(self._model_access):
      self._update_job(job, sz_key)
Exemple #6
0
  def _schedule_jobs(self):
    # Don't schedule jobs if the frequency is None
    if self._schedule_frequency is None:
      return None

    # Only perform a diff check if jobs have been scheduled
    if self._last_job_scheduling is not None:
      ts = utc_now().timestamp()

      # If the last scheduling timestamp plus the frequency is greater than the
      # current timestamp, it is not yet time to schedule.
      if self._last_job_scheduling + self._schedule_frequency > ts:
        return None

    with transaction(self._model_access):
      cr, _ = self._model_access.callproc("schedule_jobs", [])
      job_count = self._model_access.get_scalar(cr)

    self._last_job_scheduling = utc_now().timestamp()
    return job_count
Exemple #7
0
 def upsert(ma, name, type, assign):
   with transaction(ma):
     assign.append(ma.find_or_upsert(UpsertTest, dict(name=name, type=type), comp=dict(name=name), return_status=True))