A real-world scenario – the Singleton pattern, part 1

As a practical use case, we will look at a database application to show the use of Singletons. Consider an example of a cloud service that involves multiple read and write operations on the database. The complete cloud service is split across multiple services that perform database operations. An action on the UI (web app) internally will call an API, which eventually results in a DB operation.

It's clear that the shared resource across different services is the database itself. So, if we need to design the cloud service better, the following points must be taken care of:

  • Consistency across operations in the database—one operation shouldn't result in conflicts with other operations
  • Memory and CPU utilization should be optimal for the handling of multiple operations on the database

A sample Python implementation is given here:

import sqlite3
class MetaSingleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(MetaSingleton, 
                cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Database(metaclass=MetaSingleton):
  connection = None
  def connect(self):
    if self.connection is None:
        self.connection = sqlite3.connect("db.sqlite3")
        self.cursorobj = self.connection.cursor()
    return self.cursorobj

db1 = Database().connect()
db2 = Database().connect()

print ("Database Objects DB1", db1)
print ("Database Objects DB2", db2)

The output of the preceding code is given here:

A real-world scenario – the Singleton pattern, part 1

In the preceding code, we can see following points being covered:

  1. We created a metaclass by the name of MetaSingleton. Like we explained in the previous section, the special __call__ method of Python is used in the metaclass to create a Singleton.
  2. The database class is decorated by the MetaSingleton class and starts acting like a Singleton. So, when the database class is instantiated, it creates only one object.
  3. When the web app wants to perform certain operations on the DB, it instantiates the database class multiple times, but only one object gets created. As there is only one object, calls to the database are synchronized. Additionally, this is inexpensive on system resources and we can avoid the situation of memory or CPU resource.

Consider that instead of having one webapp, we have a clustered setup with multiple web apps but only one DB. Now, this is not a good situation for Singletons because, with every web app addition, a new Singleton gets created and a new object gets added that queries the database. This results in unsynchronized database operations and is heavy on resources. In such cases, database connection pooling is better than implementing Singletons.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.157.54