Skip to content

TILs

Fueling Curiosity, One Insight at a Time

At Codemancers, we believe every day is an opportunity to grow. This section is where our team shares bite-sized discoveries, technical breakthroughs and fascinating nuggets of wisdom we've stumbled upon in our work.

  1. GiritharanSystem Analyst
    What is happening behind the scenes after we configured database credentials in database.yml
    • Conduct the three-way handshake to establish a TCP connection to the server.
    • Exchange preferences and requirements with the database software to establish the session parameters.
    • Perform database authentication checks to establish the client's identity.
    • PostgreSQL supports several authentication methods, such as passwords (plaintext or MD5),GSSAPI, SSPI, and more.
    • The client (Rails, via ActiveRecord) can now send commands to the server. Commands are typically SQL statements. These statements are sent as simple text strings in the 'Query' message format.
    How Number of connection affects the database server
    • When the number of connections or pools to a server increases, CPU usage will rise. This increased demand for memory and CPU resources can affect other operations, such as transaction speeds. Managing many connections can also reduce the effectiveness of the database and decreasing overall system performance.
    What will happen if we give more connections then we configured in PSQL?
    • When that limit of a db is reached, additional connection requests are rejected.
    How connections b/w rails and PSQL established and maintained?
    • Connection pooling is a technique where database connections are reused for multiple requests instead of being closed after each query. This approach uses a connection pooler, a software that manages the connections between the database and its client applications, optimizing the use of resources and improving performance.
    • Establishing the connections is a fairly long operation.
    • Connection pooler is sitting b/w client and server. client connects to the connection pooler instead of directly to the database. Req is sent to pooler and the pooler interprets queries returns back the response from DB.
    • Once the response is returned it closes the connection. But the thing here is opening and closing connection is not overhead comparatively with client and DB connections.
    #orm #activerecord #psql #rails
  2. GiritharanSystem Analyst
    Dup vs clone while dealing with Active Record:
    • Dup creates a new record with a blank ID, which will create a new object on the database with a new ID after hitting .save.

    Ruby

    user = User.first
    user1 = user.dup
    user1:
    <User id: nil, name: "Rails">


    • clone creates a new record with the same ID, after hitting save on the clone object this will overwrite the existing data.

    Ruby

    user = User.first
    user1 = user.clone
    <User id: 1, name: "Rails">


    • If you change some value on the above attribute and put .save it will overwrite the original obj.
    #dupvsclone #ruby #rails
  3. In Rails, the resources method provides a convenient way to define RESTful routes for our application's resources. Instead of manually specifying separate routes for each CRUD action (Create, Read, Update, Delete), we can use the resources method to define all these routes with a single line of code.


    Code

    # config/routes.rb
    
    Rails.application.routes.draw do
      resources :students
    end


    With this single line of code, Rails automatically generates the following RESTful routes for the students resource:


    Code

    GET     /students          # Index action (display a list of students)
    GET     /students/new      # New action (display a form to create a new student)
    POST    /students          # Create action (create a new student)
    GET     /students/:id      # Show action (display details of a specific student)
    GET     /students/:id/edit # Edit action (display a form to edit a specific student)
    PATCH   /students/:id      # Update action (update a specific student)
    PUT     /students/:id      # Update action (update a specific student)
    DELETE  /students/:id      # Destroy action (delete a specific student)


    #rails #routes
  4. In a Rails application, the seeds.rb file is used to populate the database with initial data. This file typically resides in the db directory of our Rails application. The data added through the seeds.rb file is often used for testing or for providing initial data in a fresh installation of the application.

    After defining the data in the seeds.rb file, we can populate the database by running the rails db:seed
    #rails #database
  5. GiritharanSystem Analyst
    Generic Classes:

    • To ensure that the function correctly infers the type of the argument passed to it and returns the same type, you can use TypeScript's generic type notation

    Code

    function identityType<Type>(prop: Type): Type {
      return prop;
    }
    identityType(1);


    • If we plan to use generic <> have to add, it tells ts compiler as the function in generic fn.
    • From the above code we can see the example, if we planned to use string we can or boolean we can. The thing is both prop and return type has to be similar
    #typescript #javascript
  6. GiritharanSystem Analyst
    Difference between any and unkown type in ts
    any:
    - The any type is a dynamic type, variables of type any can hold values of any data type, and TypeScript type checking is effectively turned off for them.
    - While any provides flexibility, it bypasses TypeScript's type checking entirely, which can lead to loss of type safety and potentially introduce bugs.

    unknown:
    - The unknown type is a type-safe counterpart of any. It represents values of an unknown type.
    - Variables of type unknown can hold values of any type, but you cannot perform operations on them without first narrowing their type or asserting a more specific type.

    Both any and unknown provide flexibility in handling values of unknown types, any completely disables type checking, while unknown enforces type safety by requiring you to explicitly narrow the type before performing operations on the value. It's generally recommended to prefer unknown over any when dealing with values of unknown types, as it helps maintain type safety in your TypeScript code.

    #typescipt #javascipt
  7. GiritharanSystem Analyst
    Classes And Functions in Ts.
    Classes:
    • Ts add helps to add type annotations for the classes.

    Code

    class User {
      constructor(public name: string, public age: number) {}
    }
    const ue = new User("github", 24);


    • In Ts we don't need to initialize the properties and values inside the constructor if we are using access modifiers in the params. TypeScript will automatically initialise and assign values to class properties.
    Getters / Setters:
    • Classes can also have accessors
    • For the getter function we can able to set return value type but for setter function we can't.
    • setter functions are always expected props.
    • If a getter exists but no setter the property is automatically readonly
    • If the type of the setter parameter is not specified, it is inferred from the return type of the getter
    • For class props always try to use _ name convention for better maintainbility.

    Code

    class User {
      private _currentCount: number = 0;
      constructor(public name: string, public age: number) {}
    
      get fetch_name(): string {
        return this._name;
      }
    
      get fetchCount(): number {
        return this._currentCount;
      }
    
      set increaseCount(prop: number) {
        this._currentCount = prop + this._currentCount;
        this.logData();
      }
    
      private logData(): void {
        console.log("Count Increased");
      }
    }
    
    const fetchUser = new User("github", 24);


    Abstract:
    • If classes or method are marked as abstract those are only for readonly purposes, means they can be only used as base class/sub class.
    • So that reason we can't create object on the class who are marked as abstract.

    Code

    abstract class Photo {
      constructor(public isCameraOn: boolean, public isFlashOn: boolean) {}
    }
    
    class Phone extends Photo {}
    const ph = new Phone(true, true);


    #typescript #javascript
  8. GiritharanSystem Analyst
    Typescript Learning

    Variable definition:
    In Typescript we can specify the type string, number and boolean like


    Code

    let myName: string = "Vijay";
        let age: number = 20;
        let isActive: boolean = false;


    Moreover, if we don't specify the type typescript automatically detects the type by itself. But end of the defining the type was a good convention.

    Function Definition:
    • For defining a function we can specify the function parameters type. Along with that we can able to set the default value. And also the return value.

    Code

    function sum(a: number, b: number = 2): number {
            return a + b;
        }


    • For Arrow function:

    Code

    let sum = (a: number, b: number = 2): number => a + b;


    Why don't use any :
    • Using any in TypeScript bypasses type checking but undermines TypeScript's static typing advantages. It's better to specify types explicitly for safer and more maintainable code.
    Array:
    With the help of the array, we can store number, string and boolean values separately and mixed.


    Code

    For String
     let users: string[] = ["a", "b", "c", "d]
    
    For Number
     let count: number[] = [1, 2, 3, 4]
    
    For boolean
    let isActive: boolean[] = [true, false]
    
    For Mixed array
     let allDate: (string | number)[] = ["a", "b", "c", 1]
     Here Array contains only integers and strings


    Void And Never:
    • void is a type that represents the absence of returning value. It's often used as the return type of function that doesn't return any value.

    Code

    function logError(msg: string): void {
        console.log(msg);
    }


    • never represents the type of values that never occur:. It's typically used as the return type of functions that never return (i.e., always throw an error).

    Code

    function throwError(message: string): never {
        throw new Error(message);
    }


    Object Type:
    • Object Types is used to pass the object as a parameter in the functions.

    Code

    function fetchData(pt: { x: number; y: number }) {
      return pt;
    }
    fetchData({ x: 3, y: 7 });


    • If we want mentioned as an optional prop we can do that with the help of ? operator

    Code

    function fetchData(pt: { x: number; y?: number }) {
      return pt;
    }
    fetchData({ x: 3 });


    Union Types:
    • It means type can be formed in two or more types, which means values can be anything from the union value.

    Code

    function sum(a: string | number) {
            return a;
        }
    Here you can see value can be anything string or number


    Type Aliases
    • When can use both object type and union type but if we want use more than once we can use Type Aliases or Interface .

    Code

    type User = {
      name: string;
      age: number;
    }
    
    function displayUser(prop: User) {
      console.log(prop.name);
      console.log(prop.age);
    }
    
    displayUser({name: 'John', age: 22})


    • Moreover on the type, we can able to do extend the values.

    Code

    type User = {
      name: string;
      age: number;
    }
    
    type Role = {
      role: string
    }
    
    type UserDeatils = User & Role & {
      address: string;
    }


    • From above you can see that the userDetails inherits the user and role props without adding extra value. So that helps to keep DRY over time.
    Interface:
    • Interface is also similar in concept to type._ it's another way to name an object type.

    Code

    interface User {
      name: string;
      age: number;
    }
    
    function displayUser(prop: User) {
      console.log(prop.name);
      console.log(prop.age);
    }
    
    displayUser({name: 'John', age: 22})


    • It allows the extending feature.

    Code

    interface User {
      name: string;
      age: number;
    }
    
    interface Role {
      role: string
    }
    interface userDetails extends User, Role {
         address: string;
    }


    • The Only difference is type not available for re-opening for adding new properties.
    Readonly and Optional:
    • with the help of that, we can mark the value as read-only or optional.

    Code

    type User = {
      readonly id: string;
      name: string;
      phone: number;
      isActive: boolean;
      email?: string;
    };


    • If we try to access id typescript will throw an exception. Also, email is not present on obj it does not make exceptions.
    Tuples:
    • Tuples are a data structure that allows you to store a fixed-size, ordered collection of elements.
    • Each element in a tuple may have a different data type. They are similar to arrays, but their size and types are fixed once they are defined.

    Code

    let myTuple: [string, number, boolean];
    myTuple = ['hello', 10, true];


    • In typles we can modify elements of the tuple using array method with different types. It doesn't show any warning we always need to be aware of it.
    Enums:
    • Enums in TypeScript are usually _used to
    represent a determined number of options for a given value.
    • TypeScript provides both numeric and string-based enums
    • Numeric enums:
    ▪︎ By default enum value starts from 0 until we explicitly mention something:

    Code

    const enum UserType {
      ADMIN,
      USER,
      GUEST,
    }


    • We can explicitly change the enum value

    Code

    const enum UserType {
      ADMIN = 10,
      USER,
      GUEST,
    }


    • so from now value goes like 11, 12 in upstream
    • String enums:
    ◦ String enums are similar to numbers, But here we can specify string instead of numeric

    Code

    const enum UserType {
      ADMIN = "admin",
      USER = "user",
      GUEST = "guest",
    }


    • Heterogeneous enums:
    ◦ We can mix up string and numeric on enum. But After string, if numeric get started we need to mention the numeric value for the first one.

    Code

    const enum UserType {
      ADMIN = "admin",
      USER = 0,
      GUEST,
    }


    • Remaining value can typescript will handles.
    #typescript #javascript
  9. In Rails, a partial is a reusable view template that allows you to encapsulate a portion of a view into a separate file. Partials are useful for organising and reusing code, especially when certain components or elements are repeated across multiple views within an application.

    We can create a partial by creating a new file with a name that begins with an underscore (_). For example, _sidebar.html.erb or _header.html.erb.

    And to render a partial within another view, use the render method with the name of the partial file (without the underscore) as an argument. For example, <%= render 'sidebar' %> will render the _sidebar.html.erb partial within the current view.

    #rails
  10. The rails routes command generates a comprehensive list of all routes defined in our Rails application, displaying the HTTP method, URL pattern, controller, and action associated with each route.

    #rails
  11. find your rails code smells by using a gem called flog . Flog finds the most tortured code in your codebase.

    Code

    gem install flog


    then run

    Code

    flog app lib


    it will print the flog score for the all files that has score more than or equal to 10. Generally we should make sure flog score should be less than 10.
    Note: The more the flog score , the more pain the code is in.
    #rails #code-smells #flog
  12. In Ruby, instance variables are variables that belong to a specific instance of a class. They are prefixed with the @ symbol and are accessible within the instance methods of that class. Instance variables allow objects to maintain state and store information unique to each instance.
    Example:


    Ruby

    class Person
      def initialize(name, age)
        @name = name
        @age = age
      end
    
      def say_intro
        puts "Hello, my name is #{@name} and I am #{@age} years old"
      end
    end
    
    # Create a new instance of Person
    person1 = Person.new("John", 18)
    
    # Call the say_intro method
    person1.say_intro


    In this example, @name is an instance variable of the Person class, representing the name of each Person object created. The initialize method is a constructor that sets the value of @name when a new Person object is created. The say_intro method uses the instance variable @name to give the intro of the person with their name and age when called.

    #ruby
  13. The docker stats command is a powerful tool provided by Docker to monitor the resource usage of running containers. It provides a real-time stream of various metrics such as CPU usage, memory usage, network I/O, block I/O, and the number of processes (PIDs) running inside each container. This command is particularly useful for performance analysis and ensuring that containers are running within their resource limits.
    Example Explanation

    Code

    docker stats db370fc6b784
    CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O       PIDS
    db370fc6b784   minikube   43.70%    1.243GiB / 2.148GiB   57.87%    35.4MB / 414MB


    #devops #docker
  14. Vaibhav YadavSenior System Analyst
    We can check the default value for a given column using postgres query like this:

    Code

    SELECT column_name, column_default
    FROM information_schema.columns
    WHERE table_name = '<table_name_placeholder>' AND column_name = '<column_name_placeholder>';


    Same can be used for constraints like is_nullable as following:

    Code

    SELECT column_name, is_nullable
    FROM information_schema.columns
    WHERE table_name = '<table_name_placeholder>' AND column_name = '<column_name_placeholder>';


    #database #postgres #query
  15. active_record_doctor performs variety of health checks to identify and rectify common database issues like missing foreign key constraints, missing NON NULL constraints, missing presence validations, incorrect presence validations on boolean columns and many more. Ref: https://github.com/gregnavis/active_record_doctor
    #rails #database
  16. Codemancers
    while integrating sentry with gitlab ip whitelisting needs to be done on gitlab server (self-hosted)
    #devops #sentry#gitlab
  17. Soniya Rayabagi
    The kubectl cordon NODE_NAME command is used in Kubernetes to mark a node as unschedulable, meaning no new pods will be scheduled onto that node. Existing pods on the node will continue to run unless explicitly terminated or moved.
    #devops #kubernetes
  18. Debugging Kubernetes pod on helm
    helm upgrade unleash-app-toggle . --debug
    Adding --debug can provide more insight if the error persists, showing exactly what values are being passed to each template.
    #devops #kubernetes #helm
  19. Avoid Using Double Quotes for Environment Variables
    When configuring the PostgreSQL user and database names in a Helm values.yaml file, I initially wrapped the values in double quotes. This led to a frustrating issue where I couldn’t connect to the database, receiving errors that the role did not exist. The double quotes were being interpreted literally, causing mismatches in authentication.
    Solution: I removed the double quotes around the environment variables in my Helm chart and reapplied the configuration. This corrected the problem, and I was then able to connect successfully to the database.
    #devops #postgres #env
  20. Codemancers
    create the redis cluster from existing backup we can use snapshot_name = <name of your backyp >
    #devops #redis #Terraform

Showing page 13 of 42

Your competitors are already using AI. The question is how fast you want to unlock the value.

  • Don't know where to start?

    AI is everywhere but it's unclear which investments will actually move your metrics and which are expensive experiments.

  • Your data isn't ready

    Most AI projects fail at the data layer. Pipelines, quality, access all need work before LLMs can deliver value.

  • Internal teams are stretched

    Your engineers are shipping product. They don't have capacity to also become AI specialists with production-grade experience.

  • Legacy systems block everything

    Aging, undocumented codebases make AI integration slow, risky, and expensive. They need to move first.

Don't worry. We've got you covered.

Start with the audit.

Book a free discovery call