Thursday 20 June 2013

Przelewy zagraniczne do Polski i wymiana walut

A teraz coś bez związku z programowaniem. Jeśli pracujesz za granicą albo spłacasz kredyt walutowy (euro/franki/etc.) to temat pewnie jest Ci znany: masz pieniądze na koncie w innym kraju (albo tylko w obcej walucie) i potrzebujesz je przelać do Polski lub przekonwertować, płacąc oczywiście jak najmniejszą prowizję. Wypróbowałem już kilka wariantów, więc przedstawię pokrótce metodę, którą aktualnie stosuję oraz parę alternatyw.
Tons of money by Paul Falardeau
Zacznę od sytuacji najprostszej, czyli kredytu walutowego: od września 2011 banki działające w Polsce muszą za darmo udostępnić klientom rachunek techniczny umożliwiający spłatę rat bez płacenia spreadu. A ten, w zależności od banku, potrafił dojść i do 6%. Tak, tyle dodatkowo oddajesz swojemu bankowi, jeśli pozwalasz mu, żeby wymieniał walutę za Ciebie. Dwa lata temu, kiedy KNF wymusił na bankach zmiany, internet wysypał kantorami online, pozwalającymi wymieniać pieniądze po kursie zbliżonym do rynkowego, z minimalną prowizją. Ze sprawdzonych przeze mnie najlepszą ofertę (prawdopodobnie ze względu na największe obroty) ma Walutomat, założony w Poznaniu przez byłych pracowników Allegro. Firma zarejestrowana jest jako kantor i podlega takiemu samemu nadzorowi Ministerstwa Finansów jak fizyczne punkty wymiany walut, co jak dla mnie jest wystarczającym uwierzytelnieniem. Prowizja za wymianę wynosi 0.2%, wpłaty i wypłaty do większości dużych banków są darmowe. Korzystając z usług banku, w którym Walutomat ma swoje konto, zazwyczaj wymiana pieniędzy zajmuje około 4 godzin, z czego większość czasu to oczekiwanie na zaksięgowanie przychodzącego przelewu przez bank. Serwis wszystkie operacje potwierdza kodami SMS, w ten sam sposób może też informować o realizacji zleceń i otrzymaniu przelewu. Jedynym mankamentem jest nieobsługiwanie przelewów zagranicznych (wymagania KNF).
Jeśli często zdarza Ci się robić zakupy w zagranicznych serwisach internetowych, warto założyć kartę płatniczą do konta walutowego (oferuje taką np. Alior) i zamiast zostawiać przewalutowanie w gestii Visa/Mastercard (ok. 4% prowizji), wykonywać je samemu.
Wariant drugi: pracujesz poza granicami Polski, ale w strefie euro. Sytuacja właściwie taka sama, jak w wariancie pierwszym, bo dzięki SEPA przelewy w obrębie Unii są bezpłatne (praktycznie - przepisy wymagają, by były "nie droższe niż lokalne"). Potrzebne Ci będzie konto walutowe w polskim banku (każdy porządny prowadzi takie za darmo). Ot i cała filozofia - przelew SEPA powinien być zaksięgowany następnego dnia roboczego, co czasem prowadzi do absurdów, bo potrafi dojść szybciej niż lokalny (Irlandia, khem, khem). Co do wymiany walut, odsyłam znów do Walutomatu, nie znalazłem tańszej alternatywy. Zdecydowanie nie wykonuj przelewu walutowego na konto prowadzone w złotówkach, bo bank skasuje do 10% za wymianę.
Najciekawiej (czytaj: najbardziej upierdliwie) robi się, gdy pracujesz poza strefą euro, np. w Wielkiej Brytanii. Splendid isolation i te sprawy. Przelewy zagraniczne z UK są drogie, w okolicach 20£ (albo i więcej, zależnie od banku). WBK udostępnia tańsze przelewy (2.5£), ale z niskimi limitami (750£) i koniecznością noszenia gotówki na pocztę. Dużo z tym zachodu. Z drugiej strony, jeśli zarabiasz naprawdę dużo, to Citi oferuje darmowe przelewy między swoimi placówkami w dowolnych krajach - ale każe sobie sporo płacić za konto które nie wykazuje wystarczających miesięcznych wpływów (1800£ + 2 Direct Debit w Wielkiej Brytanii / 5000 zł w Polsce). Najwygodniejszym rozwiązaniem, jakie dotychczas znalazłem, jest TransferWise (link z moim identyfikatorem polecającego, pierwsza wymiana bez prowizji). Normalna prowizja jest wyższa niż w Walutomacie, bo 0.5% (minimum 1£), ale brak opłaty za przelew znacząco zwiększa jej atrakcyjność. Z prostych obliczeń wychodzi, że poniżej 6500£ w jednej transakcji tańszy będzie TransferWise (zakładając 20£ za przelew). Teoretycznie wymiana może trwać do 4 dni roboczych, moje jak dotąd realizowane były w około 4 godziny (od przelewu w Wielkiej Brytanii do wpłynięcia pieniędzy na konto w Polsce). Firmę założył pierwszy pracownik Skype; siedzibę mają w Shoreditch, wylęgarni londyńskich start-upów, są też zarejestrowani w brytyjskim Financial Services Authority jako pośrednik w międzynarodowym transferze pieniędzy. Od czerwca oferuje też alternatywę dla pobierania płatności (usługi typu PayPal) pod nazwą GetPaid.
Podsumowując te wszystkie opcje w jednym akapicie: jeśli potrzebujesz wymienić waluty w Polsce - skorzystaj z Walutomatu. Jeśli chcesz przekazywać pieniądze do/z Wielkiej Brytanii albo Stanów Zjednoczonych, skorzystaj z TransferWise.

Sunday 19 May 2013

SquashFS Portage tree saving time and space

Gentoo Portage, as a package manager, has one annoying side-effect of using quite a lot of disk space and being, generally, slow. As I was looking to reduce the number of small file writes that emerge --sync inflicts on my SSD, I've came back to an old and dusty trick - keeping your portage tree as a SquashFS file. It's much faster than the standard setup and uses less (76MB vs almost 400MB) disk space. Interested? Then read on!

Squashes by Olivia Bee

Requirements:

  • SquashFS enabled in the kernel: File systems -> Miscellaneous filesystems -> <M> SquashFS 4.0 - Squashed file system support and [*] Include support for ZLIB compressed file systems
  • Installed sys-fs/squashfs-tools
  • Distfiles moved out of the portage tree, e.g. (in /etc/portage/make.conf): DISTDIR="/var/squashed/distfiles"

I'm also assuming that your /tmp folder is mounted as tmpfs (in-memory temporary file system) since one of the goals of this exercise is limiting the amount of writes emerge --sync inflicts on the SSD. You are using an SSD, right?

You will need an entry in /etc/fstab for /usr/portage:

/var/squashed/portage /usr/portage squashfs ro,noauto,x-systemd.automount 0 0

This uses a squashed portage tree stored as a file named /var/squashed/portage. If you are not using systemd then replace ro,noauto,x-systemd.automount with just ro,defaults.

Now execute mv /usr/portage/ /tmp/ and you are ready to start using the update script. Ah yes, forgot about this part! Here it is:

#!/bin/bash
# grab default portage settings
source /etc/portage/make.conf
# make a read-write copy of the tree
cp -a /usr/portage /tmp/portage
umount /usr/portage
# standard sync
rsync -avz --delete $SYNC /tmp/portage && rm /var/squashed/portage
mksquashfs /tmp/portage /var/squashed/portage && rm -r /tmp/portage
mount /usr/portage
# the following two are optional
eix-update
emerge -avuDN system world

And that's it. Since the SquashFS is read only, this script needs to first make a writeable copy of the tree (in theory, this is doable with UnionFS as well, but all I was able to achieve with it were random kernel panics), then updates the copy through rsync and rebuilds the squashed file. Make sure you have a fast rsync mirror configured.

For me, this decreased the on-disk space usage of the portage tree from over 400MB to 76MB, cut the sync time at least in half and made all emerge/eix/equery operations much faster. The memory usage of a mounted tree will be about 80MB, if you really want to conserve RAM you can just call umount /usr/portage when you no longer need it.

Monday 8 April 2013

Designing a public API

Disclaimer: a bit over a month ago I've joined the API team at 7digital. This post was actually written before that and stayed in edit mode far too long. I've decided not to update it, but instead to publish it as it is with the intention of writing a follow-up once I have enough new interesting insights to share.

The greatest example of what comes from a good internal API that I know of is Amazon. If you're not familiar with the story the way Steve Yegge (now from Google) told it, I recommend you read the full version (mirrored, original was removed). It's a massive post that was meant for internal circulation but got public by mistake. There's also a good summary available (still a long read). Steve followed up with an explanation after Google PR division learnt that he released his internal memo in public. If you're looking for an abridged version, there's a good re-cap available at API Evangelist.

motorway at night by Haxonite

I'd recommend you read all of those, but preferably not right now (apart from the 2-minutes re-cap in the last link), as it would take a better part of an hour. A single sentence summary is: you won't get an API, a platform others can use, without using it first yourself, because a good API can't, unfortunately, be engineered, it has to grow.

So to start on the service-oriented route, you have to first take a look at how various existing services your company has interact with each other. I am sure you will find at least one core platform, even if it's not recognised as such, with existing internal consumers. It's probably a mess. Talk to anyone who worked with those projects (probably most programmers) and you'll have lots of cautionary tales how API can go wrong, especially when you try to plan it ahead and don't get everything right. And you won't, it's just not possible.

Some of the lessons I've learnt so far (I'm sure others can add more!):

  1. You need to publish your API.

    Last team I was with did this, sort of - we had NuGet packages (it's a .Net API, not a web one, ok?). Still, those packages contain actual implementation, not only surface interfaces, so they are prone to breaking. And they expose much more than is actually needed/should be used, so a whole lot of code is frozen in place (see 2.).
  2. You need a deprecation mechanism.

    Your API will change. Projects change, and API needs to reflect this. It's easy to add (see next point), but how do you remove? Consumers of the API don't update the definition packages, we've had cases where removing a call that was marked as [Obsolete] for over a year broke existing code.
  3. You need to listen to feedback from consumers.

    Internal consumers are the best, because you can chat with them in person. That's the theory, at least, I've seen project teams not talk to each other and it becomes a huge problem. Because of problems/lacks in API, we had projects doing terrible things like reading straight from another database or even worse, modifying it. This won't (hopefully) happen with an external consumer, but if the other team prefers to much around in your DB instead of asking for an API endpoint they need, you don't have a working API.
  4. Your API needs to perform.

    Part of the reason for problems mentioned in 3. is that our API was slow at times. There were no bulk read/update methods (crucial for performance when working with large sets of items), we had bulk notification in the form of NServiceBus queues but it had performance problems as well. If the API is not fast enough for what it's needed for, it won't be used, it's that simple.
  5. You need to know how your API is used.

    This last point is probably the most important. You won't know what you can remove (see 2.) or what is too slow (see 4.) if you don't have some kind of usage/performance measurement. Talk to your Systems team, I'm sure they will be happy to suggest a monitoring tool they already use themselves (and they are the most important user of your reporting endpoints). For Windows Services, Performance Counters are a good start, most administrators should already be familiar with them. Make sure those reports are visible, set up automatic alarms for warning conditions (if it's critical it's already too late to act). Part of this is also having tests that mirror actual usage patterns (we had public interfaces that weren't referenced in tests at all) - if a public feature does not have automated test then forget about it, it could as well not exist. Well unless you consider tests "we have deleted an unused feature and a month later found out another project broke" (see 2.).

In summary, the shortest (although still long!) path to a useful public API is to use it internally. Consumers with a quick feedback cycle are required to create and maintain a service-oriented architecture, and there's no faster feedback than walking to your neighbour's desk.