0

I am using Python and Flask as part of a server. When the server starts up, it connects to an Oracle database and Binance Crypto Exchange server

The server starts in either TEST or PRODUCTION mode. In order to determine the mode to use when starting up, I take an input variable and then use it to determine whether or not to connect to the PROD configuration (which would actually execute trades) and the TEST system (which is more like a sandbox)

Whenever I make a call to the server ( ex: http://<myservername.com>:80/ ) it seems as though the server connections are executed with each call. So, if I type in http://<myservername.com>:80/ 7 times, the code that connects to the database (and the code that connects to the Binance server) is EXECUTED SEVEN times.

Question: Is there a place where one can put the connection code so that it is executed ONCE when the server is started up?

I saw the following:

  1. https://damyan.blog/post/flask-series-structure/
  2. How to execute a block of code only once in flask?
  3. Flask at first run: Do not use the development server in a production environment

and tried using the solution in #2

@app.before_first_request
def do_something_only_once():

The code was changed so it had the following below (connection to the Binance server is not shown):

@app.before_first_request
def do_something_only_once():

    system_access = input(" Enter the system access to use \n-> ")

    if ( system_access.upper() == "TEST" ) :
        global_STARTUP_DB_SERVER_MODE   = t_system_connect.DBSystemConnection.DB_SERVER_MODE_TEST
        print(" connected to TEST database")

    if ( system_access.upper() == "PROD" ) :
        global_STARTUP_DB_SERVER_MODE   = t_system_connect.DBSystemConnection.DB_SERVER_MODE_PROD
        print(" connected to PRODUCTION database")

When starting the server up, I never get an opportunity to enter "TEST" ( in order to connect to the "TEST" database). In fact, the code under the area of:

@app.before_first_request
def do_something_only_once():

is never executed at all.

Question: How can one fix the code so that when the server is started, the code responsible for connecting to the Oracle DB server and connecting to the Binance server is only executed ONCE and not every time the server is being accessed by using http://<myservername.com>:80/

Any help, hints or advice would be greatly appreciated

TIA

@Christopher Jones Thanks for the response.

What I was hoping to do was to have this Flask server implemented as a Docker process. The idea is to start several of these processes at one time. The group of Docker Processes would then be managed by some kind of Dispatcher. When an http://myservername.com:80/ command was executed, the connection information would first go to the Dispatcher which would forward it to a Docker Process that was "free" for usage. My thoughts were that Docker Swarm (or something under Kubernetes) might work in this fashion(?) : one process gets one connection to the DB (and the dispatcher would be responsible for distributing work).

I came from ERP background. The existence of the Oracle Connection Pool was known but it was elected to move most of the work to the OS processing level (in that if one ran "ps -ef | grep <process_name>" they would see all of the processes that the "dispatcher" would forward work to). So, I was looking for something similar - old habits die hard ...

Casey Harrils
  • 2,793
  • 12
  • 52
  • 93
  • 1
    Use the singleton pattern if you just want to run something once. And also if you want to take input in server bootup time, use system args or flags. – dedsec Jun 04 '21 at 16:52
  • Thanks for the response. "use system args or flags" - that makes sense – Casey Harrils Jun 04 '21 at 17:00
  • " singleton pattern if you just want to run something once" - might I ask what is this – Casey Harrils Jun 04 '21 at 17:00
  • OK, will look at this to follow: https://www.youtube.com/watch?v=sJ-c3BA-Ypo – Casey Harrils Jun 04 '21 at 17:39
  • Singleton is a pattern where you create an instance once in runtime and every other time when you try to create an instance of the same class you will get the previously created instance. You can read my article on this - https://dev.to/ananto30/singleton-in-python-3pdk – dedsec Jun 04 '21 at 17:56

1 Answers1

0

Most Flask apps will be called by more than one user so a connection pool is important. See How to use Python Flask with Oracle Database.

You can open a connection pool at startup:

if __name__ == '__main__':
 
    # Start a pool of connections
    pool = start_pool()

    ...

(where start_pool() calls cx_Oracle.SessionPool() - see the link for the full example)

Then your routes borrow a connection as needed from the pool:

    connection = pool.acquire()
    cursor = connection.cursor()
    cursor.execute("select username from demo where id = :idbv", [id])
    r = cursor.fetchone()
    return (r[0] if r else "Unknown user id")

Even if you only need one connection, a pool of one connection can be useful because it gives some Oracle high availability features that holding open a standalone connection for the duration of the application won't give.

Christopher Jones
  • 9,449
  • 3
  • 24
  • 48
  • Thanks for the response. I made an entry above. – Casey Harrils Jun 05 '21 at 14:34
  • 1
    Sounds like https://www.oracle.com/cloud-native/functions/ With your plans, you might lose caching benefits. Try and avoid closing the processes, since this will definitely lose the caches, and require future connection re-establishment. With long-lived processes I would still recommend using a connection pool with size 1 (if each process has one user) and acquiring/releasing the connection to the pool so that you get Oracle HA features. You might find that it's better to use a multi-threaded app that handles multiple users - then scale out to multiple processes if needed. – Christopher Jones Jun 07 '21 at 02:03