Monday, December 2, 2024

MAD2-Viva-Preparation1

 "MAD2 Viva - Preparations: Tips, Resources, and Strategies"

"Preparing for the MAD2 Viva can feel overwhelming, but with the right strategies and resources, you can approach it with confidence. This post covers essential tips, key topics, and effective preparation techniques."

WebSocket Vs WebHooks

WebSocket is a protocol that provides a full-duplex communication channel over a single, long-lived TCP connection. This allows both the client and the server to send and receive data at any time.

WebSockets are a full-duplex communication protocol that enables continuous, real-time communication between a client (web browser) and a server.

Key Features:

  • Real-time, bidirectional communication: Both the client and server can initiate data exchange.
  • Persistent connection: Once established, the WebSocket connection remains open, eliminating the need for repeated requests.
  • Low latency: Ideal for scenarios where updates need

Common Use Cases:

  • Real-time chat applications (e.g., Slack, WhatsApp Web).
  • Live notifications (e.g., stock price updates, sports scores).
  • Collaborative tools (e.g., Google Docs, live whiteboards).
  • Gaming or streaming (e.g., multiplayer games, live video).

How It Works:

  1. A WebSocket connection is established via a handshake over HTTP/HTTPS.
  2. Once the handshake completes, the connection is upgraded to the WebSocket protocol.
  3. Both parties can exchange messages freely.

 Webhooks

Webhooks are HTTP callbacks used to send data from one system to another when an event occurs. They are event-driven but not persistent connections.

Key Features:

  • One-Way Communication: Data flows from the webhook sender (server) to the receiver (client).
  • Event-Driven: Triggered by specific events (e.g., new user signup, payment completed).
  • Stateless: Each webhook is a separate HTTP request; no persistent connection is needed.
  • Pull-Style: The receiver must set up an endpoint to accept data.

Common Use Cases:

  • Sending notifications when events happen (e.g., GitHub push events).
  • Payment processing (e.g., Stripe sending a webhook for a successful payment).
  • Order updates in e-commerce platforms.
  • Integrating third-party services (e.g., Zapier, Slack incoming webhooks).

How It Works:

  1. The client sets up an endpoint (URL) to accept webhooks.
  2. The server sends an HTTP POST request to the client's endpoint whenever the event occurs.
  3. The client processes the data sent in the request.

When to Use?

  • Use WebSockets when:

    • You need continuous, real-time, bidirectional communication.
    • Examples: live chats, collaborative tools, gaming, real-time notifications.
  • Use Webhooks when:

    • You need event-based, one-way communication.
    • Examples: receiving updates from third-party services, notifications on external events.

Can we swap the order of two decorators @roles_required and @auth_required?

Yes, you can swap the order of two decorators like @roles_required and @auth_required, but the effect may vary depending on their implementation. Here’s why and what to consider:


How Decorators Work

Decorators are applied in the order they appear, from top to bottom in the code. When you stack multiple decorators:

  1. The outer decorator (closest to the function) wraps the function first.
  2. The inner decorator (farthest from the function) is applied to the result of the outer decorator.

This order determines how the decorators interact and process the request.


Scenario: @roles_required and @auth_required

Common Usage

  1. @auth_required: Ensures that the user is authenticated.
    • If the user is not authenticated, it stops further execution (e.g., redirects to login).
  2. @roles_required: Ensures the authenticated user has the required role(s).
    • Assumes the user is already authenticated.

Order 1:

python

@roles_required('admin') @auth_required def some_function(): pass
  • What Happens:
    • @auth_required is applied first, ensuring the user is authenticated.
    • Only if authentication passes does @roles_required check the user’s role.
  • Result: This is the correct and common order because it makes sense to check authentication first and roles second.

Order 2:

python

@auth_required @roles_required('admin') def some_function(): pass
  • What Happens:
    • @roles_required is applied first, checking the user’s role.
    • If role checking requires the user to be authenticated, this may fail or raise an error if the user is not authenticated yet.
    • Outcome depends on implementation:
      • If @roles_required depends on user authentication but doesn’t explicitly enforce it, it may cause issues.
      • If @roles_required enforces authentication internally, it may work, but this would be redundant if @auth_required is also applied.

Best Practice

  • Use @auth_required first, followed by @roles_required, as checking roles logically depends on the user being authenticated:
    python
    @roles_required('admin') @auth_required def some_function(): pass

Why Does Order Matter?

  • Logical Flow: It’s logical to authenticate the user first before checking their roles.
  • Error Handling: Swapping the order may lead to errors or redundant checks if the inner decorator (e.g., @roles_required) assumes authentication is already handled.
  • Code Readability: Following a clear order (auth → roles → others) improves readability.
prioritize tasks in Celery?
To prioritize tasks in Celery, you can use queues and routing with different priority levels. Celery's prioritization allows tasks to be processed in an order that reflects their importance, ensuring critical tasks get executed before less important ones.

1.Use Queues for Task Prioritization

Celery supports the concept of task queues. You can define multiple queues, each assigned a priority level, and then route tasks to the appropriate queue.

Steps:

  • Define multiple queues with priority levels (e.g., high_priority, low_priority).
  • Assign tasks to specific queues.
example:
from celery import Celery 
app = Celery('my_app', broker='redis://localhost:6379/0'

@app.task(queue='high_priority') 
def critical_task(data): 
  print("Processing critical task:", data) 

@app.task(queue='low_priority') 
def non_critical_task(data): 
  print("Processing non-critical task:", data)

2. Assign Task Priority with a Message Broker

If you are using RabbitMQ or Redis as your message broker, you can use the task's priority feature.

Supported Message Brokers:

  • RabbitMQ: Fully supports task priorities.
  • Redis: Supports simple queue-based prioritization (via sorted lists or separate queues).

3. Use Worker Concurrency to Prioritize Tasks

You can assign dedicated workers to specific queues to ensure critical tasks are always processed first.

Run Workers for Specific Queues:

Start workers that handle specific queues:

bash code
celery -A my_app worker --queues=high_priority --concurrency=4 celery -A my_app worker --queues=low_priority --concurrency=2

4. Dynamic Task Routing

You can route tasks dynamically based on their importance

Important Ponits

  • Use multiple queues (e.g., high_priority, low_priority).
  • Assign task priorities in RabbitMQ or use queue-based sorting in Redis.
  • Start workers with specific queues or concurrency limits to process critical tasks faster.
  • Dynamically route tasks based on runtime conditions.
  • Monitor and adjust resource allocation to meet changing requirements.
  • The purpose of Index? Index on two columns in SQLAlchemy?

    Purpose of an Index in SQL

    An index in a database improves the performance of query operations by allowing faster retrieval of rows. It acts like a "lookup table" that the database uses to speed up data searches.

    1.Faster Query Execution

    2.Efficient Sorting and Filtering

    3.Enforce Uniqueness

    • Unique indexes prevent duplicate values in a column.
    • Example: A unique index on email ensures that no two users have the same email.

    4.Support Joins:

    • Speeds up joins by indexing the columns involved in foreign key relationships.

    Index on Two Columns

    A composite index (or multicolumn index) is an index that includes more than one column. It helps optimize queries that filter or sort using multiple columns together.

    SELECT * FROM orders WHERE customer_id = 1 AND order_date = '2024-11-29';

    Index on Two Columns in SQLAlchemy

    In SQLAlchemy, you can define a composite index using the Index class.

    Defining an Index on Two Columns in SQLAlchemy

    You can create a multi-column index in SQLAlchemy using the Index class or the indexes parameter in the model definition.

    Using Index

    The Index object allows explicit declaration of multi-column indexes.

    example:

    from sqlalchemy import Index, Column, Integer, String

    from sqlalchemy.ext.declarative import declarative_base


    Base = declarative_base()


    class MyTable(Base):

        __tablename__ = 'my_table'

        id = Column(Integer, primary_key=True)

        column1 = Column(String)

        column2 = Column(String)


        # Define an index on column1 and column2

        __table_args__ = (

            Index('ix_column1_column2', 'column1', 'column2'),

        )

  • ix_column1_column2: The name of the index (you can choose any meaningful name).
  • 'column1', 'column2': The columns included in the index.
  • No comments:

    Post a Comment

    Mangerial Economics Quiz1 solutions Guide

    Mangerial Economics Quiz1 solutions Guide  solutions watch on you tube channel