# Bank Renege

Covers:

- Resources: Resource

- Condition events

A counter with a random service time and customers who renege. Based on the program bank08.py from TheBank tutorial of SimPy 2. (KGM)

This example models a bank counter and customers arriving at random times. Each customer has a certain patience. She waits to get to the counter until she’s at the end of her tether. If she gets to the counter, she uses it for a while before releasing it.

New customers are created by the `source` process every few time steps.

    """
    Bank renege example

    Covers:

    - Resources: Resource
    - Condition events

    Scenario:
      A counter with a random service time and customers who renege. Based on the
      program bank08.py from TheBank tutorial of SimPy 2. (KGM)

    """
    import random

    import simpy

    RANDOM_SEED = 42
    NEW_CUSTOMERS = 5  # Total number of customers
    INTERVAL_CUSTOMERS = 10.0  # Generate new customers roughly every x seconds
    MIN_PATIENCE = 1  # Min. customer patience
    MAX_PATIENCE = 3  # Max. customer patience

    def source(env, number, interval, counter):
        """Source generates customers randomly"""
        for i in range(number):
            c = customer(env, f'Customer{i:02d}', counter, time_in_bank=12.0)
            env.process(c)
            t = random.expovariate(1.0 / interval)
            yield env.timeout(t)

    def customer(env, name, counter, time_in_bank):
        """Customer arrives, is served and leaves."""
        arrive = env.now
        print(f'{arrive:7.4f} {name}: Here I am')

        with counter.request() as req:
            patience = random.uniform(MIN_PATIENCE, MAX_PATIENCE)
            # Wait for the counter or abort at the end of our tether
            results = yield req | env.timeout(patience)

            wait = env.now - arrive

            if req in results:
                # We got to the counter
                print(f'{env.now:7.4f} {name}: Waited {wait:6.3f}')

                tib = random.expovariate(1.0 / time_in_bank)
                yield env.timeout(tib)
                print(f'{env.now:7.4f} {name}: Finished')

            else:
                # We reneged
                print(f'{env.now:7.4f} {name}: RENEGED after {wait:6.3f}')

    # Setup and start the simulation
    print('Bank renege')
    random.seed(RANDOM_SEED)
    env = simpy.Environment()

    # Start processes and run
    counter = simpy.Resource(env, capacity=1)
    env.process(source(env, NEW_CUSTOMERS, INTERVAL_CUSTOMERS, counter))
    env.run()

The simulation’s output:

    Bank renege
     0.0000 Customer00: Here I am
     0.0000 Customer00: Waited  0.000
     3.8595 Customer00: Finished
    10.2006 Customer01: Here I am
    10.2006 Customer01: Waited  0.000
    12.7265 Customer02: Here I am
    13.9003 Customer02: RENEGED after  1.174
    23.7507 Customer01: Finished
    34.9993 Customer03: Here I am
    34.9993 Customer03: Waited  0.000
    37.9599 Customer03: Finished
    40.4798 Customer04: Here I am
    40.4798 Customer04: Waited  0.000
    43.1401 Customer04: Finished