Skip to content

Instantly share code, notes, and snippets.

@omerkaya1
omerkaya1 / post_large_file.go
Created August 16, 2019 11:59
Post a large file using io.Pipe() so that we don't need to read the whole file into memory
func (c *ClientImpl) PostLargeFile(reader io.ReadCloser, formParams map[string]string) (io.ReadCloser, error) {
r, w := io.Pipe()
writer := multipart.NewWriter(w)
defer r.Close()
go func() {
defer w.Close()
defer reader.Close()
for key, val := range formParams {
@omerkaya1
omerkaya1 / custom-tables.component.html
Last active February 11, 2020 08:13
Create dynamic table out of an arbitrary Object (which may as well be a JSON Object)
<table mat-table [dataSource]="tableData" style="width: 100%">
<ng-container [matColumnDef]="col" *ngFor="let col of tableData[0] | keys">
<th mat-header-cell *matHeaderCellDef> {{ col }} </th>s
<td mat-cell *matCellDef="let element"> {{ element[col] }} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="tableData[0] | keys"></tr>
<tr mat-row *matRowDef="let row; columns: tableData[0] | keys;"></tr>
</table>
@omerkaya1
omerkaya1 / rabbitmq.go
Created February 1, 2021 07:23
An interface and an implementation of the message queue service
package mq
import (
"context"
"time"
"github.com/pkg/errors"
"github.com/streadway/amqp"
)
job "api-gw" {
datacenters = ["dc1"]
type = "service"
# Update policy
update {
max_parallel = 1
min_healthy_time = "10s"
healthy_deadline = "3m"
progress_deadline = "10m"
auto_revert = true
@omerkaya1
omerkaya1 / pprof.sh
Created October 29, 2022 10:45
Simple script to collect Go app's profile
#!/bin/bash
BRANCH=$(git branch --show-current)
COMMIT_HASH=$(git rev-parse --short HEAD)
for i in {1..5} ; do
printf "Phase %s\n" "$i"
if ! curl -s "localhost:8000/debug/pprof/heap" > mem-"$BRANCH"-"$COMMIT_HASH"-"$(date "+%Y-%m-%d-%H-%M-%S")".pprof
then
echo "failed to get mem profile"
@omerkaya1
omerkaya1 / artillery.yml
Created October 29, 2022 10:48
Artillery config file (load testing WebSocket)
config:
environments:
local:
target: "http://localhost:8000"
phases:
- duration: 10
arrivalRate: 1
arrivalCount: 200
maxVusers: 50
name: "Warm up"
WITH get AS (
SELECT id FROM table_name WHERE name=$1
), new AS (
INSERT INTO table_name (name) VALUES ($1) ON CONFLICT (name) DO NOTHING RETURNING id
)
SELECT id FROM get
UNION ALL
SELECT id FROM new;
WITH ranked_records AS (
SELECT row_number() OVER (PARTITION BY user_id, user_id ORDER BY created_at DESC) AS rn,
id, some_other_column, created_at
FROM user_status WHERE user_id IN (?)
)
SELECT
id, some_other_column, created_at
FROM ranked_records
WHERE rn=1
ORDER BY user_id;
@omerkaya1
omerkaya1 / delete_with_cte.sql
Created April 6, 2023 07:20
Delete records from multiple tables in one query with CTE
WITH
first AS (
DELETE FROM table1 WHERE condition1
RETURNING *
),
second AS (
DELETE FROM table2 WHERE condition2
RETURNING *
),
-- add more analogous delete statements
@omerkaya1
omerkaya1 / pool.go
Created September 22, 2023 15:53
A sized pool of slices of generic type objects
// SizedPool is a channel-based pool of slices objects.
// It retains an arbitrary number of slices of objects and ensures their initial capacity.
type SizedPool[T any] struct {
pool chan []T
cap int
}
func NewSizedPool[T any](size int, cap int) *SizedPool[T] {
return &SizedPool[T]{
pool: make(chan []T, size),