http://golang.org/doc/code.html

이걸 따라하고나면 GOPATH는 잡혀있을 것이다.

근데 자꾸 없다고 난리리. 문제는 sudo로 실행해서 그런것!

permission 문제는 아래 명령어로 해결해준다.

sudo chown -R "$USER:" "$GOPATH"


References

1. http://stackoverflow.com/questions/24778565/go-go-get-gopath-error-when-gopath-is-set

2. http://stackoverflow.com/questions/21463261/package-download-fails-gopath-not-set-why

'Go' 카테고리의 다른 글

Goroutine context switching 시점  (0) 2018.04.20
How to run go app in heroku by your own project (with github)  (0) 2017.02.24
LITE IDE setup  (0) 2015.01.28
블로그 이미지

시간을 거스르는자

,

import pytz

import datetime

import calendar


s = '2012/01/10 23:00'

def get_timezone_offset_ms(timezone_name):

    try:

        tz = pytz.timezone(timezone_name)

    except Exception as e:

        return 0

    timezone_offset = datetime.datetime.now(tz).strftime('%z')

    offset_sign = timezone_offset[0:1]

    offset_hour = int(offset_sign+timezone_offset[1:3])

    offset_min = int(offset_sign+timezone_offset[3:])

    offset_ms = offset_hour*60*60*1000 + offset_min*60*1000

    return offset_ms


def get_pst_timestamp_from_time_string(time_string, time_format):

    pst_timezone_name = "America/Los_Angeles"

    tz_offset_ms = get_timezone_offset_ms(pst_timezone_name)

    t = datetime.datetime.strptime(time_string, time_format)

    return long(calendar.timegm(t.timetuple())*1000) - tz_offset_ms


get_pst_timestamp_from_time_string(s, '%Y/%m/%d %H:%M')

'python' 카테고리의 다른 글

gunicorn vs uwsgi  (0) 2017.01.20
flask async response  (0) 2017.01.04
functools.wraps에 대해  (0) 2015.04.15
Apple Push Notification Service(APNs) python modules  (0) 2015.04.07
Shallow copy VS Deep copy  (0) 2014.08.27
블로그 이미지

시간을 거스르는자

,

그놈의 timezone 그리고 망할 DST때문에 한동안 머리가 아팠다.

하지만 결국 답을 얻었다. 컴퓨터는 항상 답이 있다. 정말 좋다. I love it!

아무튼. 방법이 뭐냐면

일단 뭐 frequency를 어떻게 하냐는 자기 맘이겠지만, 일단 하루로 하고

1. 하루에 한번씩 모든 timezone name(예를 들어 Asia/Seoul)을 쭉 가져와서 각각의 offset을 테이블로 저장해서 redis나 memory 변수에 들고 있는다.

뭐 대강 이런 느낌일 것이다.

{

"+0900": ['Asia/Seoul', 'Asia/..', '...']

"+0830": [....],

....

}

이렇게 해보면 약 40개정도의 offset키에 모든 타임존 리스트가 정리되어진다.


2. 이제 우리에게 필요한 것은 푸시 예약이다.

푸시 예약은 두가지 방법으로 할 수 있다. 첫번째는 UTC기준 두번째는 각 지역기준.

만약 UTC기준이라면 전체 타임존에 동일한 시점에 일괄 발송하겠다는 것이다. 이때는 위에서 만든 타임존 오프셋 테이블을 쓸 필요없이 그냥 그 UTC시간이 되었을떄 일괄 발송하면된다.

두번째가 관건이다. 이것을 위해 이짓을 하는거니까. 바로 지역시간 기준.

자 지역시간 기준 12:00. 각 지역이 12:00가 되었을때 푸시를 보내는 것이다.

일단 12시를 UTC로 저장해 놓고 매 분 도는 스케줄러가 저 오프셋 테이블의 키값을 가져와서 UTC 시간에 오프셋을 더해서 그게 현재 시간이면 그에 해당하는 타임존 녀석들에게 푸시를 보내는 것이다. (물론 이것을 위해서는 유저정보에 타임존 네임이 있어야 할것이다)


자 나는 이렇게 구현할거고 서비스 할것이다. 으하하하 

'서버 교양' 카테고리의 다른 글

Docker overview  (0) 2015.06.13
SSL 인증서 발급  (0) 2015.03.04
글로벌 푸시 보내기  (0) 2014.11.27
mongodb만 쓰면 mysql을 과연 안써도 될까?  (0) 2014.04.23
쿠키런 서버사이드 이야기  (0) 2014.04.04
블로그 이미지

시간을 거스르는자

,

[Redis] HSET vs SET

redis 2015. 1. 9. 11:53

멀까 뭘써야할까?

SET은 그냥 키 벨류

HSET은 키 하나에 여러개를 쪼개서 넣을 수 있다.

예를 들어 유저 id를 Hash키로 잡고 {nickname: 'John', age:35}  이렇게 id에 국한된 데이터를 한데 저장할 수 있다.

검색을 해보면 계산시간에 대해 다음과 같은 말도 있다.

SET은 키 문자열 그대로 저장하고 써서 찾아내는 CPU 계산 시간이 빠르다.
HSET은 키 문자열을 한번 짧은 길이로 바꿔서 저장하기 때문에 요고 맵핑하는 계산이 한번 더 들어간다. 그러나 이 시간은 최대 ziplist(키 encode/decode할때 쓰는 code리스트 인듯) 크기만큼 든다. 

키를 겁네 많이 저장해놓고 쓰는 경우가 많아서 메모리를 효율적으로 쓰기위해선 HSET을 쓰는게 좋다. 라고 생각할 수도 있겠지만 결국은 "어떤 자료구조를 쓸 것인가"가 중요하다고 한다.

그냥 키 벨류한쌍이 필요한 거면 SET을 쓰고, 위와같이 ID에 묶여있는 정보들을 쓸거면 HSET을 쓰고.


Reference

1. http://stackoverflow.com/questions/12779372/hset-vs-set-memory-usage

2. http://grokbase.com/t/gg/redis-db/12a89re9n7/hset-vs-set-memory-usage

'redis' 카테고리의 다른 글

zscore list copy  (0) 2016.10.12
redis sentinel  (0) 2015.11.30
블로그 이미지

시간을 거스르는자

,

아직 구현된건 아니고 생각일뿐.

문제) 모든 유저에게 오후 1시에 푸시 메시지를 보내고 싶다. 그런데 세계의 각 지역은 당연히 시간이 다르거니와 같은 국가라도 시간이 다르며 또한 섬머타임으로 인해 같은 지역이라 해도 시간이 변동된다.


방법)

1. 유저는 회원가입할때 아래 정보를 서버에게 알려준다.

 - utc_offset(dst time적용되지 않았을때 offset), dst_offset(dst 적용되었을때 offset), dst_starttime, dst_endtime


2. 서버에서 푸시 예약 등록을 할때 13시 정보에 대해서 모든가능한 offset에 대해서 schedule 예약을 해둔다.

예) -12 ~ +14 까지.

이중에서 offset +2 가 보내질 시간이 되면 디비에서 다음에 해당하는 그룹을 가져와서 푸시를 보낸다.

그룹 1) utc_offset 이 2 이고 start, end time이 없는 유저 그룹

그룹 2) dst_offset 이 2 이고 now가 start, end time에 포함되는 그룹


근데 start end time 필드를 넣어놓고 쿼리 때리는게 넘 느려보인다.. 


블로그 이미지

시간을 거스르는자

,

Revoking task

celery 2014. 11. 24. 18:50

task revoke를 한다음에 다시 scheduled task를 가져오면 이전에 revoke된것들이 포함되어있다. 알고보니 revoked가 따로 있음 -_-

아직 revoke된거를 제외한 나머지 task만 가져오는건 못찾음.. 일단 revoke 안된것만 가져오는건 두 배열을 비교하는 수 밖에..


from celery.task.control import inspect

from celery.task.control import revoke


i = inspect()

queues = i.scheduled()

queues_revoked = i.revoked()

keys = queues.keys()

all_tasks = []

revoked_tasks = []

tasks = []


if len(keys) > 0:

    all_tasks = queues[keys[0]]

    revoked_tasks = queues_revoked[keys[0]]


for task in all_tasks:

    if task['request']['id'] not in revoked_tasks:

        revoke(task['request']['id'], terminate=True) 


블로그 이미지

시간을 거스르는자

,

예약 푸시

celery 2014. 11. 20. 15:58

Schduled push

http://docs.celeryproject.org/en/latest/reference/celery.app.task.html?highlight=apply_async#celery.app.task.Task.apply_async

apply_async eta 파라미터로 datetime object를 넘겨주면됨.

블로그 이미지

시간을 거스르는자

,

ubuntu t2.micro magnatic 8GB


$ sudo apt-get update

* LC_ALL 설정

/home/ubuntu/.bashrc 에 다음 추가

export LC_ALL="en_US.UTF-8"

* shell update

source .bash_profile



* mongoDB 설치

(http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/)


* mongoDB Setting

Now configure the following MongoDB parameters by editing the configuration file /etc/mongod.conf:

dbpath = /data
logpath = /log/mongod.log

* db path에 db폴더 만들고 권한 바꿔주기

$ sudo mkdir /data/db

$ sudo chown ubuntu /data/db


* 몽고 서비스 시작

$ sudo service mongod start


* For deployment

$ sudo apt-get install git

$ sudo apt-get install libxml2-dev libxslt1-dev python-dev

# $ sudo apt-get install python-pip

wget http://peak.telecommunity.com/dist/ez_setup.py

sudo python ez_setup.py

$ sudo easy_install requests==2.3.0

$ sudo easy_install -U pip


nginx

1
2
3
4
sudo aptitude install software-properties-common;
sudo add-apt-repository ppa:nginx/development;
sudo apt-get update;
sudo apt-get install nginx;

* 몇몇 mac과 별도로 설치한 module들

$ sudo pip install --no-use-wheel --upgrade distribute

$ sudo pip install cssselect

$ sudo apt-get install python-lxml

$ sudo pip install w3lib

$ sudo pip install tzlocal

$ sudo apt-get install nodejs (for javascript runtime)

$ sudo pip install futures


* server / job log file 생성

$ mkdir server/log

$ touch server/log/log.txt

$ touch server/log/job.txt

$sudo chown -R mongodb:mongodb /data /log /journal
* mongod 띄울때 기본적으로 localhost 만 붙을 수 있도록

bind_ip = 127.0.0.1

설정이 되어있다. remote에서 붙게 하려면 이걸 빼줄것!


'aws' 카테고리의 다른 글

kinesis firehose 삽질일기  (0) 2017.03.16
How to EC2 disk and memory usage monitoring  (0) 2015.03.27
elasticache dump to file  (1) 2015.03.23
HTTP 505: HTTP Version Not Supported  (0) 2014.07.09
boto s3 Broken pipe error  (0) 2014.04.25
블로그 이미지

시간을 거스르는자

,

1. install

brew install nginx


2. configuration

/user/local/etc/nginx/nginx.conf

보통 위 conf에서 server부분을 따로 따서 각 필요한 서버마다 만들어놓고 include 해서 쓴다고 한다.

따라서,

/user/local/etc/nginx/sites-available/mysite

를 만들고 아래와 같이 설정한다.

upstream frontends {

server 127.0.0.1:12000;

server 127.0.0.1:12001;

# fair no_rr;

}


server {

listen 15000;


# Allow file uploads

client_max_body_size 1M;


location / {

try_files $uri $uri/ @node;

}


location @node{

proxy_pass_header Server;

proxy_set_header Host $http_host;

proxy_redirect off;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Scheme $scheme;

proxy_pass http://frontends;

}


location ^~ /static {

alias /Users/ytkang/Development/webtoon/static;

}


# location /nginx_status {

# stub_status on;

# access_log off;

# allow 127.0.0.1;

# deny all;

# }

} 



그리고 /usr/local/etc/nginx/sites-enabled/에 사용할 것들을 넣어놓고 쓰는 형태로 많이들 쓴다고 한다.

따라서 위에서 만든 놈을 여기에 링크를 걸자

ln -s /usr/local/etc/nginx/sites-available/mysite /usr/local/etc/nginx/sites-enabled/mysite

그리고 sites-enabled에 있는놈을 config 파일에서 import

$ vim /usr/local/etc/nginx/nginx.conf

 include       /usr/local/etc/nginx/sites-enabled/*;

* 주의할 점은 이미 nginx.conf에 있는 설정중 mysite에 있는 설정과 겹치는 부분은 지워줘야! 또한 sites-enabled/default도 지워줘야!


3. start / restart

서버 시작: $ sudo nginx

서버 재시작: $ sudo nginx -s reload


* 만약 위 설정중 "fair no_rr"을 사용하려고 한다면

nginx: [emerg] unknown directive "fair"

이런 에러를 직면할 것이다. 이는 fair를 사용하려면 따로 깔아야하기 때문!

여기서 설치: http://wiki.nginx.org/HttpUpstreamFairModule


'nginx' 카테고리의 다른 글

Loadbalancer를 통해서 올때 client ip가 전달되도록하는 방법  (0) 2018.01.12
nginx log ratation  (0) 2015.04.06
ssl setting  (0) 2015.03.12
블로그 이미지

시간을 거스르는자

,

5rocks 고찰

mornitoring 2014. 9. 11. 16:59

Case. 이전 10일동안 들어오지 않은 유저에게 보상을 보내서 들어오게 하고싶다.

1. 이 유저들에게 푸시를 보내야 한다.

2. 이 유저들이 들어왔을때 보상을 주는 팝업을 띄운후 그 팝업을 본 유저들에게 보상을 줘야 한다.

문제점: 

 - 푸시는 특정 시간 이전에 계산된 지표로 보내진다. 따라서 2번 조건(실시간 캠패인. 캠패인 은 푸시와 다르게 실시간으로 조건이 맞는 유저에게 보내진다.)에 오늘까지가 들어간다면 상이한 결과가 나타날 수 있다. (푸시를 받았는데 보상은 없는등..) 

 - 유저 분류가 디바이스 기준이다. 따라서 두개의 디바이스를 사용한적이 있는 유저고 앱이 둘다 깔려있다면, 하나의 디바이스에서 조건이 맞으면 푸시와 보상을 챙길수 있다. (한명의 유저가 두개의 다른 데이터를 가지고 있게되는 현상)

블로그 이미지

시간을 거스르는자

,