프로그래밍 358

[CloudFlare] Workers Log 편하게 보는 법

wrangler tail Worker에 찍은 console.log들을 편하게 보고싶은데, CF에서 제공하는 Real-time Logs는 내가 원하는 정보보다 방대하다. 아래는 그 로그의 예시인데, "logs" 부분에 당시 내가 찍은 console.log가 있다면 담기는 식이다. 실패한 요청만 필터링을 거는 등 스마트하게 로그를 보고싶다면 wrangler tail 명령어를 이용하면된다. { "outcome": "ok", "scriptName": "entrypoint", "exceptions": [], "logs": [], // ****** 바로 여기 !! ********* "eventTimestamp": 1675348988505, "event": { "request": { "url": "https://....

[안드로이드] ExoPlayer 깜빡거리거나 검은 화면(Black screen)이 뜰 때

문제발생 Epoxy로 무한 반복되는 배너 캐러셀에 동영상을 적용시키는 중에, 간혹 동영상이 재생될때 검은 화면만뜨고 재생이 안되거나 깜빡이는 문제가 있었다. *하나의 ExoPlayer를 RecyclerView.Adapter에서 재활용해가면서 쓰는 사례다. 정신차리고 setPlayer() Document를 자세히 읽어보니... Player를 다른 View에 붙일때 switchTargetView()를 쓰는걸 추천한다고 되어있다. 하지만 setPlayer()를 직접 쓰고자 할 경우 이전 View에서 Player를 분리하기 위해 setPlayer(null)을 호출하기 이전에 새로운 View에 Player를 연결시켜야 한다. *switchTargetView를 직접 써보려고 했으나, 지원하지 않는 메소드였다. 해결..

[안드로이드] java.lang.IllegalStateException: An instance of OnFlingListener already set 해결

문제 발생 @ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT) internal class PagerSnapHelperCarousel @JvmOverloads constructor( context: Context ) : Carousel(context) { init { if (onFlingListener == null) { PagerSnapHelper().attachToRecyclerView(this) } } } Epoxy의 Custom Carousel로 SnapHelper를 붙이는 도중 OnFlingListener가 이미 등록되어있다는 오류가 발생했다. 당연하게도 이유는 RecyclerVIew에 OnFlingListener가 이미 등록되어 있어..

[TypeScript] satisfies 연산자 알아보기

satisfies operator satisfies는 TypeScript 4.9 버전 부터 새롭게 추가된 연산자로, 업캐스팅(up-casting)으로 Type-safety를 보장한다. 💡 업캐스팅? 부모 - 자식 상속관계의 클래스가 있을때 부모 → 자식 방향의 형변환을 다운캐스팅, 자식 → 부모 방향의 형변환을 업캐스팅이라 한다. Parent p = new Parent(); Child c = new Child(); Parent p2 = (Parent) c; // 업캐스팅 Child c2 = (Child) p2; // 다운캐스팅 Typescript의 경우 한 타입이 다른 타입의 값을 모두 포함하고 있으면 상속관계가 된다. 사용 예시를 바로 보자. Versions는 VersionRecord를 satifsfi..

CloudFlare KV로 앱 점검시간 관리하기

왜 Cloudflare Worker? 개발중인 앱 실행시 스플래시 화면에서 진입점(Entrypoint)을 결정하고 간단한 정보들을 내려주는 API가 있다. 포함되는 데이터는 API 서버 URL, 앱 버전 업데이트 정보, 점검시간 정보 등 앱 실행을 위한 필수정보들이다. 이는 CloudFlare Worker 로 구현되어있는데, 아래와 같은 이유로 채택하게 되었다. 앱 API 서버와 별개로 동작할 것: 서비스 점검 등으로 서버가 다운되었을때도 정보를 전달할 수 있다. 빠르고 안정적인 응답을 내려줄 것: Cloudflare 전역 네트워크 위에서 돌아가서 50ms 이내 응답이 가능하다. 수정 및 배포가 용이할 것: JS를 써서 언어적 장벽도 낮고 Wrangler라는 CLI를 제공해서 배포가 편리하다. 요구사항:..

[AppsScript] 스프레드 시트 Row 업데이트한 날짜 자동으로 적는 법

행에 수정이있을경우, 수정한 날짜를 자동으로 기록하는 방법을 소개한다. AppsScript는 여러 트리거들을 제공하는데, 몇몇 함수들이 예약되어있다. 그 중에서도 셀의 편집때 자동으로 트리거되는 onEdit(e) 함수를 사용해서 셀의 변화가 일어날때마다 업데이트 날짜를 찍어주는 만들어 보았다. 구글 스프레드시트 > 확장 프로그램 > Apps Script 메뉴에 들어가, 아래 코드를 붙여넣고 저장한다. HTML 삽입 미리보기할 수 없는 소스 사진의 시트를 기준으로 작성된 코드이므로 하나하나 뜯어서보자면, UPDATED_COLUMN은 날짜를 적을 컬럼의 위치다. 그리고 HEADER_ROW_LENGTH는 헤더부분의 길이를 나타내는데, 헤더를 수정했다고해서 업데이트 날짜가 찍히면 안되니 그 이상의 Row에서 수..

Docker로 마인크래프트 서버 관리하기 - 고급편

⚠️ 들어가며 서버를 여는 방법은 초급편글에 있습니다. 초급편과는 달리, 약간의 컴퓨터 지식이 필요할 수 있습니다. 하지만 끈기와 의지가 있으신 분들이라면 충분히 따라할 수 있으실겁니다. 주제가 광범위하기 때문에 Q&A 형식으로 포스팅했습니다. ⛔️ docker: Error response from daemon: Conflict 오류가 떠요 이미 동일한 내용의 docker container가 올라가서 그렇습니다. 아래 명령어로 마크 서버 컨테이너를 삭제하고 다시 시도해보시면 될겁니다. docker stop mc && docker rm mc 🧾 Server.properties를 바꾸고 싶어요 ex) 최대 플레이어 수 늘리기 최대 플레이어 수를 늘리려면 vim으로 server.properties를 직접 수정..

[무료] 마인크래프트 서버 쉽게 열고 관리하기 - 초급편 (자바, 베드락)

⚠️ 들어가며 이글은 GCP로 마인크래프트 서버여는법 Step 6부터 시작합니다. 컴퓨터에 관한 지식이 거의 전무해도 따라할 수 있는 정도를 목표로합니다. 🐳 1. Docker 설치하기 Docker는 쉽게 말하면 컴퓨터안에 가상으로 컴퓨터를 띄울 수 있도록 해주는 프로그램입니다. 우리는 Docker로 마인크래프트 서버를 띄울 것입니다. 무슨말인지 모르셔도 상관없습니다! 앞선 글을 따라 Step6까지 진행하셨다면 터미널을 띄운 상태일 것입니다. * Ubuntu OS를 기준으로 합니다. sudo apt-get update && \ sudo apt-get install ca-certificates curl gnupg lsb-release -y && \ sudo mkdir -p /etc/apt/keyrings ..

[Kotlin] CompletableDeferred의 개념과 활용

Promise가 그리울때 이벤트 기반으로 통신하는 프로토콜을 구현중에, JS의 Promise나 Dart의 Completer와 비슷한 역할을 하는 Kotlin 친구가 없을까하다 찾게되었다. 완벽한 대체재다! CompletableDeferred는 public function을 이용해 완료하거나 취소할 수 있는 Deferred이다. 이를 활용하면 내가 원하는 시점까지 기다렸다가 값을 받을 수 있다. 그럼 SuspendableCoroutine이랑 뭐가 다르냐? 라는 생각이 들 수 있다. SuspentableCoroutine은 해당 블록 안에서만 complete/cancel을 제어할 수 있지만, CompletableDeferred는 그런 제약이 없다. CompletableDeferred : Functions ab..

Kotlin coroutine : async vs launch 차이

async vs launch async 결과를 반환하는 코루틴을 시작하는데 사용 예외(Exception)가 발생할 경우 결과를 반환에 포함한다. 결과 또는 예외를 포함하는 Deferred를 반환 launch 결과를 반환하지 않는 코루틴을 시작하는데 사용 본인 혹은 자신 코루틴의 실행을 취소하기위해 사용할 수 있는 Job을 반환 Job: Fire and forget Job Job은 생성될때 기본적으로 자동 시작된다. 하지만, 이를 자동시작 되지 않게하려면 CoroutineStart.LAZY를 사용할 수 있다. Job join() vs start() join: Job을 완료할때까지 대기한다. start: 애플리케이션이 Job이 완료될때까지 기다리지 않는다. Job의 라이프 사이클 New: 생성됨 Active..