<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><description>A Meetup, Inc “behind the scenes” look at what our engineering team is working on.</description><title>Making Meetup</title><generator>Tumblr (3.0; @makingmeetup)</generator><link>http://making.meetup.com/</link><item><title>Moving Day</title><description>&lt;p&gt;We’re hosting our blog on Medium now. Make your way over &lt;a href="https://medium.com/making-meetup" target="_blank"&gt;there&lt;/a&gt;.&lt;br/&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/157867135237</link><guid>http://making.meetup.com/post/157867135237</guid><pubDate>Wed, 01 Mar 2017 11:57:25 -0500</pubDate><dc:creator>richmeetup</dc:creator></item><item><title>White House LGBTQ Tech and Innovation Summit</title><description>&lt;p&gt;I was fortunate enough to be invited to a gathering of &lt;a href="http://lesbianswhotech.org/attendees/" target="_blank"&gt;LGBTQ tech leaders at the White House&lt;/a&gt; to discuss and help address how tech and innovation could help issues ranging from social justice, to climate change, to women in tech.&lt;/p&gt;&lt;figure data-orig-width="2992" data-orig-height="4000" class="tmblr-full"&gt;&lt;img src="http://68.media.tumblr.com/3e3954503b0703f753176d215ecbf917/tumblr_inline_ocq6p6ok1z1u0rkvc_540.jpg" alt="image" data-orig-width="2992" data-orig-height="4000"/&gt;&lt;/figure&gt;&lt;p&gt;&lt;a href="https://www.whitehouse.gov/administration/eop/ostp/about/leadershipstaff/smith" target="_blank"&gt;Megan Smith&lt;/a&gt; was one of our event hosts, and I was so impressed with the way she approached the world’s issues with such a deep knowledge, optimism, and ambition for solving them.&lt;/p&gt;&lt;figure data-orig-width="3024" data-orig-height="4030" class="tmblr-full"&gt;&lt;img src="http://68.media.tumblr.com/8e033dbca6d2ce7454905a9c046915b5/tumblr_inline_ocq6qmgIMK1u0rkvc_540.jpg" alt="image" data-orig-width="3024" data-orig-height="4030"/&gt;&lt;/figure&gt;&lt;p&gt;In the afternoon we broke out into unconference style working groups to start planning the &lt;a href="https://wetechup.com/" target="_blank"&gt;TechUP&lt;/a&gt; Inclusion + Innovation Week in DC in November. I chose the Women &amp;amp; Girls group and it was there that I was able to listen and speak with others about how to create an event that tangibly helped increase the exposure and inclusion of women and girls in tech.&lt;/p&gt;&lt;figure data-orig-width="960" data-orig-height="720" class="tmblr-full"&gt;&lt;img src="http://68.media.tumblr.com/5c59bd695c16ecacc7cb3ec4227ce8e5/tumblr_inline_ocq6nyWqUD1u0rkvc_540.jpg" alt="image" data-orig-width="960" data-orig-height="720"/&gt;&lt;/figure&gt;&lt;p&gt;It was a great event and I was overwhelmed with the concentration of brilliant, visionary, and humble tech leaders assembled in one place.  I learned a great deal just speaking with as many people as I could.&lt;/p&gt;&lt;figure data-orig-width="960" data-orig-height="718" class="tmblr-full"&gt;&lt;img src="http://68.media.tumblr.com/03a90430dfd99c4ea41a843e7a22c514/tumblr_inline_ocq6rgMfSm1u0rkvc_540.jpg" alt="image" data-orig-width="960" data-orig-height="718"/&gt;&lt;/figure&gt;&lt;p&gt;Thanks so much to &lt;a href="http://lesbianswhotech.org/about/" target="_blank"&gt;Leanne Pittsford&lt;/a&gt; and the &lt;a href="http://lesbianswhotech.org/" target="_blank"&gt;Lesbians Who Tech&lt;/a&gt; community for inviting me and organizing such an impactful event.  It was one of the most inclusive and diverse tech events I’ve ever been to, so a huge props to Leanne and the crew for intentionally making that happen.&lt;br/&gt;&lt;/p&gt;&lt;figure data-orig-width="4032" data-orig-height="3024" class="tmblr-full"&gt;&lt;img src="http://68.media.tumblr.com/6ddfb22cc270108a67ae728bfc3dd649/tumblr_inline_ocq6urKUMk1u0rkvc_540.jpg" alt="image" data-orig-width="4032" data-orig-height="3024"/&gt;&lt;/figure&gt;</description><link>http://making.meetup.com/post/149699878977</link><guid>http://making.meetup.com/post/149699878977</guid><pubDate>Tue, 30 Aug 2016 10:00:31 -0400</pubDate><category>diversity</category><category>innovation</category><category>women in tech</category><category>lgbtq</category><category>white house</category><category>inclusion</category><dc:creator>yvette-meetup</dc:creator></item><item><title>More Than Binary: Inclusive Gender Collection and You</title><description>&lt;figure data-orig-width="990" data-orig-height="372" class="tmblr-full"&gt;&lt;img data-orig-width="990" data-orig-height="372" src="http://68.media.tumblr.com/e504e49cd4f33b7f5c15e2de8f700f94/tumblr_inline_o8xabnmw7I1tzbr9n_540.gif"/&gt;&lt;/figure&gt;&lt;p&gt;This year, I was fortunate enough to be accepted to speak at a few tech conferences about a side project I’ve been working on over the past year. My project Gender Amender (&lt;a href="https://github.com/anne-decusatis/genderamender" target="_blank"&gt;https://github.com/anne-decusatis/genderamender&lt;/a&gt;) exists to collect gender information in a way that’s meaningful for both machine learning algorithms and people of all genders.&lt;/p&gt;&lt;p&gt;I just returned from PyCon (&lt;a href="https://us.pycon.org/2016/" target="_blank"&gt;https://us.pycon.org/2016/&lt;/a&gt;) less than two weeks ago, which was a wonderful conference. I found the emphasis on community there to be inspiring and refreshing.&lt;/p&gt;&lt;p&gt;I’ll also be speaking at Open Source Bridge next week (&lt;a href="http://opensourcebridge.org/sessions/1779" target="_blank"&gt;http://opensourcebridge.org/sessions/1779&lt;/a&gt;) - I’m really looking forward to it, and I’d love to see you there!&lt;/p&gt;&lt;p&gt;If you can’t make it to see me speak in person and want to look at my talk resources online, or if you want to see all the sources I used, then you can find all that information in one place at my personal blog: &lt;a href="http://anne.loves.technology/blog/talks/2016/05/16/more-than-binary.html" target="_blank"&gt;http://anne.loves.technology/blog/talks/2016/05/16/more-than-binary.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I’d like to thank all of my coworkers at Meetup for helping make this possible and for listening to me practice this talk over and over again for weeks and weeks.&lt;/p&gt;&lt;p&gt;&lt;i&gt;Anne DeCusatis is a Core Engineer on Meetup’s Retention team.&lt;/i&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/146074014432</link><guid>http://making.meetup.com/post/146074014432</guid><pubDate>Fri, 17 Jun 2016 15:53:20 -0400</pubDate><category>meetup engineering</category><category>gender</category><category>technology</category><category>pycon2016</category><category>open source bridge 2016</category><category>osb16</category><dc:creator>anne-meetup</dc:creator></item><item><title>Scaladays NYC 2016</title><description>&lt;p&gt;&lt;strong&gt;This year, Meetup had the honor of sponsoring Scaladays NYC as well as hosting the official conference afterparty. For those unfamiliar with Scaladays, it is one of the largest yearly Scala conferences, often held in multiple cities around the world. This year’s conference in New York City had over six hundred attendees and almost sixty talks spread across four tracks over the course of two and a half days. Needless to say, myself and four other Meetup engineers had blast attending the conf.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://storage.googleapis.com/making_meetup/Scaladays%20NYC%202016/IMG_20160509_171337.jpg" alt=""/&gt;
(Opening keynote by Martin Odersky)&lt;/p&gt;

&lt;p&gt;Some of our favorite talks in no particular order include (but are not limited to):&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Data Structures of the Dark Side by Shimi Bandiel (@shimib)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Roll Your Own Shapeless by Daniel Spiewak (@djspiewak)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implicits Inspected and Explained by Tim Soethout (@TimSoethout)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DDD and Onion Architecture in Scala by Wade Waldron (@wdwaldron)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scala Goes Native by Denys Shabalin (@den_sh)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Two personal favorites of mine were Domain Driven Design and Onion Architecture by Wade Waldron and Being Creative with Genetic Algorithms and Typeclasses by Noel Markham (@noelmarkham). In his DDD talk, Wade illustrated DDD concepts via ‘the domain of cooking an egg,’ and even shared some sample code (&lt;a href="https://github.com/WadeWaldron/scaladays2016" target="_blank"&gt;https://github.com/WadeWaldron/scaladays2016&lt;/a&gt;).  Noel’s talk was more Scala-centric, and was focused on explaining typeclasses by implementing a fun genetic algorithm which attempted to recreate the Mona Lisa.&lt;/p&gt;

&lt;p&gt;(Side note: If anyone is interested in genetic algorithms, there’s a fun race car simulation that can be found here: &lt;a href="http://rednuht.org/genetic_cars_2/" target="_blank"&gt;http://rednuht.org/genetic_cars_2/&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;We also got to hear directly from some folks at Lightbend (formerly TypeSafe) and the &lt;a href="https://www.epfl.ch/" target="_blank"&gt;École polytechnique fédérale de Lausanne (EPFL)&lt;/a&gt; who are helping push the boundaries of Scala development. I would highly recommend checking out EPFL’s Dotty project, which “is a platform to try out new language concepts and compiler technologies for Scala” (&lt;a href="https://github.com/lampepfl/dotty" target="_blank"&gt;https://github.com/lampepfl/dotty&lt;/a&gt;). Other exciting projects that were presented at the conference included enhancements to Scala.js, a registry for Scala libraries, and also taking Scala native by providing memory management features to Scala developers (&lt;a href="https://github.com/densh/scala-offheap" target="_blank"&gt;https://github.com/densh/scala-offheap&lt;/a&gt;). The EPFL also announced the launch of the Scala Center, a new initiative that will act as the open source foundation for Scala with representatives from both the community as well as industry.&lt;/p&gt;

&lt;p&gt;And of course, no conference is complete without a popping afterparty, hosted at your’s truly: Meetup HQ. We were pleasantly surprised at the turnout and had a great time mingling and hearing about all the exciting things (Scala and non-Scala related) our peers in the tech community are pursuing.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://storage.googleapis.com/making_meetup/Scaladays%20NYC%202016/ScaladaysNYCAfterParty2016-2.jpg" alt=""/&gt;
(Yay party!)&lt;/p&gt;

&lt;p&gt;We were even blessed by the attendance of Scala’s creator Martin Odersky, along with many other luminaries of the Scala community.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://storage.googleapis.com/making_meetup/Scaladays%20NYC%202016/IMG_2675.JPG" alt=""/&gt;
(Meetup + Martin Odersky + Friends)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If any of the above post was remotely interesting to you and you’d like to find out more about what we’re all about here at Meetup, check out these interviews with our engineers (&lt;a href="http://making.meetup.com/tagged/hiring" target="_blank"&gt;http://making.meetup.com/tagged/hiring&lt;/a&gt;)!&lt;/strong&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/144823411557</link><guid>http://making.meetup.com/post/144823411557</guid><pubDate>Mon, 23 May 2016 17:09:35 -0400</pubDate><category>scala</category><category>scaladays</category><category>meetup</category><category>engineering</category><dc:creator>confoundead</dc:creator></item><item><title>Meetup Core Engineering Manager Jake Levine on Phone Interviews</title><description>&lt;p&gt;Ever wonder what to expect during a phone screen? Core Engineering Manager Jake Levine provides some insight into our process at Meetup with an interview with our friends at &lt;a href="http://devpost.com/" target="_blank"&gt;Devpost&lt;/a&gt;. If you missed our last interview with Devpost on culture fit, check that out &lt;a href="http://making.meetup.com/post/143164276182/meetup-engineerings-rich-hsieh-on-culture-fit" target="_blank"&gt;here&lt;/a&gt;.&lt;br/&gt;&lt;/p&gt;&lt;iframe allowfullscreen="" src="https://www.youtube.com/embed/JnJpmuhupuQ" frameborder="0" height="315" width="560"&gt;&lt;/iframe&gt;&lt;p&gt;If you want to learn more about our hiring process and read some 1-on-1′s with our engineering team, go to our &lt;a href="http://devpost.com/teams/meetup" target="_blank"&gt;Devpost team page&lt;/a&gt;. &lt;br/&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/143893761322</link><guid>http://making.meetup.com/post/143893761322</guid><pubDate>Thu, 05 May 2016 10:29:33 -0400</pubDate><category>devpost</category><category>hiring</category><category>meetup</category><category>phonescreens</category><category>jake levine</category><dc:creator>richmeetup</dc:creator></item><item><title>Meetup Engineering’s Rich Hsieh on Culture Fit</title><description>&lt;p&gt;This week, Meetup&amp;rsquo;s own Rich Hsieh sat down with the folks at Devpost where they talked about culture fit. What exactly is it?  And how is it valued at a company like Meetup?  Check out the discussion here:&lt;/p&gt;

&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/YS1SrwmPAEg" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;And then check out our awesome Devpost page where you can read more about what it&amp;rsquo;s like to work at Meetup, and what the interview process here is like.  And you can check out all of our openings!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devpost.com/teams/meetup" target="_blank"&gt;http://devpost.com/teams/meetup&lt;/a&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/143164276182</link><guid>http://making.meetup.com/post/143164276182</guid><pubDate>Thu, 21 Apr 2016 09:50:49 -0400</pubDate><category>devpost</category><category>hiring</category><category>meetup</category><category>culture fit</category><category>rich hsieh</category><dc:creator>jakemeetup</dc:creator></item><item><title>Making Meetup’s Apps @ Mobile Week NYC</title><description>&lt;p&gt;Last week I was fortunate enough to give the keynote at &lt;a href="http://mobileweek.co/" target="_blank"&gt;Mobile Week NYC&lt;/a&gt;.  It was entitled “&lt;i&gt;It’s Time! What to do When Rebuilding Your App?&lt;/i&gt;” and is a case study in how Meetup made the exciting (and difficult) decision to rebuild and redesign our apps. &lt;/p&gt;&lt;figure data-orig-width="1920" data-orig-height="1080" class="tmblr-full"&gt;&lt;img src="http://68.media.tumblr.com/8f773042a07c3960b8c57f65e1cda1b8/tumblr_inline_o5ukhw1YWc1u0rkvc_540.png" alt="image" data-orig-width="1920" data-orig-height="1080"/&gt;&lt;/figure&gt;&lt;p&gt;The keynote meant to answer the big question: “&lt;i&gt;Once teams are spun up and start working on a project like this, then what?&lt;/i&gt;”  Here are a few of the key Android and iOS engineering topics I covered in my talk.&lt;/p&gt;&lt;p&gt;&lt;b&gt;iOS&lt;/b&gt;&lt;/p&gt;&lt;p&gt;One of the biggest decisions we had to make around rebuilding our apps was with our iOS app.  Some background on our iOS app is that it was originally built in a 3 month extended hackathon type project back in 2009 by two engineers that did an awesome job getting an MVP shipped. The problem was, it was never re-written over the course of 6 years, accumulating a lot of technical debt. We knew the code wasn’t of the quality we wanted and our test coverage was way too low for our current standards.  &lt;/p&gt;&lt;p&gt;Also, much of the institutional knowledge from those who had built the app over 6 years was gone, so we hired — in our opinion — the best mobile engineering shop in NYC — &lt;a href="http://lickability.com/" target="_blank"&gt;Lickability&lt;/a&gt; — to do an in-depth analysis of our codebase. Their output was a spreadsheet of every class in the app (almost 500 classes!), a recommendation as to whether or not the class was salvageable, and metrics around the test coverage.&lt;/p&gt;&lt;figure data-orig-width="1920" data-orig-height="1080" class="tmblr-full"&gt;&lt;img src="http://68.media.tumblr.com/4363f74fa49c348b785829b865d5a8b2/tumblr_inline_o5uko6UfS51u0rkvc_540.png" alt="image" data-orig-width="1920" data-orig-height="1080"/&gt;&lt;/figure&gt;&lt;p&gt;Following such a detailed assessment, we had the data to know that we needed to re-write almost our entire model code. Naturally, in a redesign you have to rewrite the view/UI code as well, so it was a clear decision for us that in order to futurize Meetup, investing more time in a new codebase that met our quality and testing standards was the right decision for us.  Futurize is one of our company values and means: “ We like shipping, but we like investing to ship faster in the future even more.”&lt;/p&gt;&lt;figure class="tmblr-full" data-orig-height="576" data-orig-width="1024"&gt;&lt;img src="http://68.media.tumblr.com/7d398fd183d4e49fb236184e914d4459/tumblr_inline_o5w0etBgAU1u0rkvc_540.jpg" data-orig-height="576" data-orig-width="1024"/&gt;&lt;/figure&gt;&lt;p&gt;After making that decision in 2015, it seemed obvious to us that if we’re going to rebuild our app, &lt;a href="https://swift.org/" target="_blank"&gt;Swift&lt;/a&gt; was the only way to go. Among many other reasons we love Swift, we especially love that it is statically typed so is type safe just like the rest of our Scala/JVM stack.&lt;/p&gt;&lt;p&gt;Once the decision was made to rebuild our iOS app from scratch, the next key decision we had to make was Swift 1 or 2, because Swift 2 was still in beta. We decided on Swift 2 because it both compiles and runs faster, is a great boost to our team’s morale to be able to start off working with and contributing to a the latest open source iOS language, and we saw it as a great way to attract people who wanted to make Meetup now using the future of iOS.&lt;/p&gt;&lt;figure data-orig-width="1920" data-orig-height="1080" class="tmblr-full"&gt;&lt;img src="http://68.media.tumblr.com/150a858bfb5a98c4bb526907391dfd65/tumblr_inline_o5ukl76Sjh1u0rkvc_540.png" alt="image" data-orig-width="1920" data-orig-height="1080"/&gt;&lt;/figure&gt;&lt;p&gt;The second decision we made was supporting iOS 9 and above for minimum version support in the new app. We had a lot of data that showed how quickly our member base would upgrade to iOS 9 and how few members would be left on iOS 8. We didn’t like that we’d leave any member behind. But, not only did the data support it, but our engineering assessment was that building for iOS 9 and above would significantly reduce the amount of code we’d need to write — freeing us up to build and ship other features faster.  Specifically, supporting iOS 9 allowed us to use the new &lt;a href="https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIStackView_Class_Reference/" target="_blank"&gt;UIStackView&lt;/a&gt; class, providing an easy interface for laying out a collection of views and leveraging Auto Layout for creating UIs that adapt to the device’s screen size and orientation.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Android&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The decision making process around building our Android app was very different. The foundation of our Android app was much better, the code quality and test coverage was much higher, and the lead engineer working on the app had already been working on it for several years.  &lt;/p&gt;&lt;p&gt;We had the institutional knowledge in house to do an assessment of the codebase and determined that we’d have to refactor and re-write significant things, but that there were parts that would serve us well in the future.  During our assessment we identified key areas we needed to address and this is how we handled them.&lt;/p&gt;&lt;p&gt;The biggest change we made was to go all in using &lt;a href="https://github.com/ReactiveX/RxJava" target="_blank"&gt;RxJava&lt;/a&gt; for reactive programming in Android. It really helps us get concurrency under control with little effort because it abstracts everything to far fewer lines of code. This was a big deal for us because we’re loading so much data from the network using multiple API calls and our API has to support many different clients at once (Android, iOS app, Apple Watch, Web). So, it’s hard for the API to always return data to a client app in a single call that’s exactly the way each client app needs it every time.&lt;/p&gt;&lt;figure data-orig-width="1920" data-orig-height="1080" class="tmblr-full"&gt;&lt;img src="http://68.media.tumblr.com/8169bf3d21ce02cf7ee6a4165fcbbcde/tumblr_inline_o5ukpwkEZS1u0rkvc_540.png" alt="image" data-orig-width="1920" data-orig-height="1080"/&gt;&lt;/figure&gt;&lt;p&gt;Our Android team absolutely loves &lt;a href="https://github.com/ReactiveX/RxJava" target="_blank"&gt;RxJava&lt;/a&gt; because they know that they can composite multiple calls on the client (meaning they can easily wait for both to complete, then do something in the app) in just few lines of code. They can do this without adding additional complexity (for example, composing &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html" target="_blank"&gt;Futures&lt;/a&gt;) or having to manage things like if a user tapped away from the screen.  It’s been the biggest improvement for us in the new app architecture.&lt;/p&gt;&lt;p&gt;We’ve also loved using &lt;a href="http://square.github.io/okhttp/" target="_blank"&gt;OKHTTP&lt;/a&gt; from Square as our HTTP client. It helps us load data from the API into the app faster, save bandwidth usage, and really make our app more responsive &amp;ndash; it just feels and works awesomely fast.  &lt;/p&gt;&lt;p&gt;We use Jackson for data processing and agree with the &lt;a href="https://github.com/FasterXML/jackson" target="_blank"&gt;Jackson Project&lt;/a&gt; page that says it’s “the best data processor for Java”. It supports every format you’d want with streaming parsing and data-binding.&lt;/p&gt;&lt;p&gt;Last, but not least, &lt;a href="https://github.com/google/guava" target="_blank"&gt;Guava&lt;/a&gt; is a set of core libraries from Google that really helped us handle a broad range of things like collections, caching, I/O, and has really reduced the amount of code we’ve needed to write ourselves.&lt;/p&gt;&lt;figure class="tmblr-full" data-orig-height="1365" data-orig-width="1024"&gt;&lt;img src="http://68.media.tumblr.com/8e4e319effec3238dfdcecc2fb587db7/tumblr_inline_o5w0cuP59P1u0rkvc_540.jpg" data-orig-height="1365" data-orig-width="1024"/&gt;&lt;/figure&gt;&lt;p&gt;&lt;b&gt;Thanks!&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Mobile Week NYC was a great experience and there were a lot of interesting talks there. Thanks to the conference organizers for inviting me to speak and to everyone who attended and participated!  I learned a lot and met many passionate, smart people doing great things in mobile. &lt;/p&gt;</description><link>http://making.meetup.com/post/143024807327</link><guid>http://making.meetup.com/post/143024807327</guid><pubDate>Mon, 18 Apr 2016 16:57:01 -0400</pubDate><dc:creator>yvette-meetup</dc:creator></item><item><title>Diversity and inclusion on Meetup’s engineering team</title><description>&lt;p&gt;Our &lt;a href="http://devpost.com/teams/meetup" target="_blank"&gt;Devpost&lt;/a&gt; site contains bios and fun facts about some of our team members, myself included. We’ve also shared &lt;a href="http://devpost.com/teams/meetup#diversity" target="_blank"&gt;data on the ethnicity and gender background for some of our employees&lt;/a&gt;, broken down by the company and our engineering team.&lt;/p&gt;

&lt;p&gt;There are many factors which go into building an inclusive culture at Meetup and this data represents only one part of the picture. A fuller portrait would include people such as our CTO, Yvette Pasqua, and other women in leadership roles. What this data does is provide a snapshot of team members who self-identify within the parameters of federally required EEO-1 reporting categories and have chosen to share this information. I care deeply about inclusion both within and beyond this. For example, this data doesn’t capture gender information aside from “male” and “female” - a topic which I &lt;a href="https://us.pycon.org/2016/schedule/presentation/2023/" target="_blank"&gt;will be speaking about at PyCon this June&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I think that sharing diversity data is a critical first step towards transparency and accountability. I’m proud to work to help create a company whose makeup reflects the diversity of our Meetup members, and to help create an industry whose makeup reflects the diversity of our world.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Anne DeCusatis is a Core Engineer on Meetup’s Retention team.&lt;/em&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/142298670108</link><guid>http://making.meetup.com/post/142298670108</guid><pubDate>Tue, 05 Apr 2016 12:00:16 -0400</pubDate><category>engineering</category><category>meetup</category><category>diversity</category><category>inclusion</category><category>tech</category><dc:creator>anne-meetup</dc:creator></item><item><title>NE Scala 2016</title><description>&lt;p&gt;Towards the end of the first week of March, on March 4th and March 5th, Meetup put together a small team of engineers who volunteered to attend the &lt;strong&gt;6th&lt;/strong&gt; annual &lt;a href="http://www.nescala.org/" target="_blank"&gt;&lt;em&gt;Northeast Scala Symposium&lt;/em&gt;&lt;/a&gt; in Philadelphia.&lt;/p&gt;

&lt;p&gt;I am an engineer on Meetup’s Member Engagement team, building a system that delivers smart and personalized notifications to members on our platform. I am also a part of Meetup’s Core Engineering team, where we are using Scala a lot in order to build out our platform. Given my work and interest in Scala, I was one of the engineers who participated in the trip, and I’d love to share some of the things I learned during Day 2 of the event!&lt;/p&gt;

&lt;p&gt;This was the first language conference I have ever attended and it was even more exciting to me, given that I only started working in Scala since I joined Meetup, almost 2 years ago, straight out of college!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://68.media.tumblr.com/tumblr_m1kn4vbKV11qbpbbro1_500.gif" alt=""/&gt;&lt;/p&gt;

&lt;h5&gt;Day 2&lt;/h5&gt;

&lt;p&gt;Day 2 was the &lt;em&gt;unconference&lt;/em&gt; day and it started with a casual meeting, in which every participant who had something to present would take a timeslot on a spreadsheet, such that at the end of the meeting we had a relative schedule for the day. After this, everyone was free to go to whichever presentation was most appealing to them.&lt;/p&gt;

&lt;p&gt;And off I went!&lt;/p&gt;

&lt;h3&gt;Early Morning Category Theory &lt;em&gt;with &lt;a href="https://twitter.com/runarorama" target="_blank"&gt;(Rúnar Bjarnason)&lt;/a&gt;&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;Eager to learn more about Scala and the theoretical background behind it (and being a math nerd), I picked &lt;em&gt;Category Theory&lt;/em&gt; as my first presentation to attend. I did not know much about what &lt;em&gt;Categories&lt;/em&gt; are in Scala and what kind of rules govern these entities, but I went in excited to learn something new.&lt;/p&gt;

&lt;p&gt;The talk started with an abstract definition of &lt;em&gt;Categories&lt;/em&gt; as collections of objects and arrows (or maps/morphisms) that define relationships between the objects. These concepts seemed very familiar to me from those of Set Theory.&lt;/p&gt;

&lt;p&gt;Rúnar went on into describing &lt;em&gt;Functors&lt;/em&gt; (maps between &lt;em&gt;Categories&lt;/em&gt;, that preserve their structure) and then explained what &lt;em&gt;Monads&lt;/em&gt;, &lt;em&gt;Monoids&lt;/em&gt; and &lt;em&gt;Comonads&lt;/em&gt; were, while also doing some whiteboard Scala examples of all of this. These topics were necessary background needed in order to answer a question posed by someone in the audience:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Prove that List is a comonad in the monoid category of List&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using the information absorbed up to that point, we were able to follow a simple proof of the statement.&lt;/p&gt;

&lt;p&gt;This was my first ever exposure to &lt;em&gt;Category Theory&lt;/em&gt; and I loved it! Rúnar&amp;rsquo;s explanations made me dig more into it after the conference!&lt;/p&gt;

&lt;h3&gt;Scalaz-Stream Workshop &lt;em&gt;with &lt;a href="https://twitter.com/runarorama" target="_blank"&gt;(Rúnar Bjarnason)&lt;/a&gt;&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;The second presentation I went to was also led by Rúnar Bjarnason, but this time it was very hands-on. He introduced us to &lt;a href="https://github.com/runarorama/ircz" target="_blank"&gt;a small IRC client &amp;amp; server&lt;/a&gt; built using &lt;a href="https://github.com/functional-streams-for-scala/fs2" target="_blank"&gt;scalaz-stream&lt;/a&gt; and everyone in the room had to implement a feature of their preference to add to it.&lt;/p&gt;

&lt;p&gt;I went on trying to implement the ability to change nicknames while in a chatroom. The process of working with &lt;em&gt;scalaz-stream&lt;/em&gt; and, implicitly, with &lt;a href="https://github.com/scalaz/scalaz" target="_blank"&gt;scalaz&lt;/a&gt; was relatively new to me since I haven&amp;rsquo;t written &lt;em&gt;pure&lt;/em&gt; functional code using &lt;em&gt;scalaz&lt;/em&gt; before, but it was a really good experience to be exposed to both of these Scala libraries.&lt;/p&gt;

&lt;p&gt;By the end of the workshop, my implementation ended up being &lt;em&gt;somewhat&lt;/em&gt; functional :)&lt;/p&gt;

&lt;h3&gt;Living with SI-2712 &lt;em&gt;with Daniel Spiewak&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;After a couple of other presentations, I got to my last presentation of the day. It was about a known Scala compiler bug and it involved a lot of live coding, type-level programming, category theory (d'oh) and just pure amazement.&lt;/p&gt;

&lt;p&gt;The gist of the presentation was a proof of concept of &lt;a href="https://issues.scala-lang.org/browse/SI-2712" target="_blank"&gt;the compiler bug&lt;/a&gt; and &lt;a href="https://gist.github.com/djspiewak/ddbaf065b33d94c68889" target="_blank"&gt;ways to get around it&lt;/a&gt;. It was very well explained and, even though the material got pretty intense towards the end, I enjoyed the deep dive!&lt;/p&gt;

&lt;h5&gt;Conclusions&lt;/h5&gt;

&lt;p&gt;I really enjoyed my time at &lt;em&gt;NE Scala&lt;/em&gt; and learned a lot of new things, from theoretical aspects of Category Theory, to more applied concepts using &lt;em&gt;pure&lt;/em&gt; functional &lt;em&gt;scalaz&lt;/em&gt;. I am very excited for the next conference I&amp;rsquo;m going to attend (or even &lt;em&gt;unconference&lt;/em&gt;, since &lt;em&gt;&lt;a href="http://event.scaladays.org/scaladays-nyc-2016" target="_blank"&gt;Scala Days 2016&lt;/a&gt;&lt;/em&gt; is approaching and will be in NYC :) )!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://cdn.playbuzz.com/cdn/b95e1ace-566a-4150-b20d-1bbb5ae9be4a/7f990315-14a7-4826-85c8-dec119984e46.gif" alt=""/&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/141623943277</link><guid>http://making.meetup.com/post/141623943277</guid><pubDate>Thu, 24 Mar 2016 17:46:47 -0400</pubDate><category>scala</category><category>conference</category><category>philadelphia</category><category>category theory</category><category>nescala</category><dc:creator>vlad-meetup</dc:creator></item><item><title>We’re hiring!</title><description>&lt;p&gt;Interested in working at Meetup? We worked with our friends at &lt;a href="http://devpost.com/" target="_blank"&gt;DevPost&lt;/a&gt; to put together a page about our engineering team. Find out details about dev process and our tech stack, plus check out interviews with our great engineers.&lt;/p&gt;&lt;p&gt;&lt;a href="http://devpost.com/teams/meetup" target="_blank"&gt;http://devpost.com/teams/meetup&lt;/a&gt;&lt;br/&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/141213616712</link><guid>http://making.meetup.com/post/141213616712</guid><pubDate>Thu, 17 Mar 2016 15:20:28 -0400</pubDate><category>hiring</category><category>devpost</category><category>engineering-team</category><dc:creator>richmeetup</dc:creator></item><item><title>At NY Historical Society - Silicon City Exhibit</title><description>&lt;p&gt;What happens when you take the Meetup engineering crew to the &lt;a href="http://www.nyhistory.org/exhibitions/silicon-city-computer-history-made-new-york" target="_blank"&gt;NY Historical Society - Silicon City Exhbit?&lt;/a&gt;

&lt;img src="http://photos4.meetupstatic.com/photos/event/b/a/0/a/highres_447467626.jpeg" alt="image"/&gt;

Someone ends up on their modern laptop in the middle of a history lesson, was he just trying to mock the Univac or was he just trying to make sure Meetup was running smoothly!

&lt;img src="http://photos3.meetupstatic.com/photos/event/b/9/e/f/highres_447467599.jpeg" alt="image"/&gt;&lt;/p&gt;&lt;p&gt;
We got to see some older progamming languages and associated mainframes.

&lt;img src="http://photos2.meetupstatic.com/photos/event/c/b/d/6/highres_447472182.jpeg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;
We saw punch cards and old satellites, like the Telstar 1, launched in 1962 it successully relayed the first television pictures, telephone calls, and fax images.

&lt;img src="http://photos3.meetupstatic.com/photos/event/c/6/f/8/highres_447470936.jpeg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;
All in all it was a great trip through the evolution of technology, which reminds us here at Meetup to continue to evolve our technologies and platform so that we can constantly improve the user experiences our organizers and members have. We love our tech, but we also love building community both inside and out of Meetup.
&lt;/p&gt;

&lt;h3&gt;More pics&lt;/h3&gt;

&lt;p&gt;
New York is home to companies who are evolving the face of technology.
&lt;img src="http://photos3.meetupstatic.com/photos/event/b/b/0/c/highres_447467884.jpeg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;
We listen intently as we learn people used to be called computers and eventually as we all know it&amp;rsquo;s what we now call the hardware.
&lt;img src="http://photos3.meetupstatic.com/photos/event/b/8/f/a/highres_447467354.jpeg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;
Always be gaming.
&lt;img src="http://photos1.meetupstatic.com/photos/event/b/a/6/6/highres_447467718.jpeg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;
Can&amp;rsquo;t blame that on auto-correct.
&lt;img src="http://photos1.meetupstatic.com/photos/event/b/a/a/7/highres_447467783.jpeg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;
I think Angry Cat is just lonely.
&lt;img src="http://photos2.meetupstatic.com/photos/event/b/b/1/7/highres_447467895.jpeg" alt="image"/&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/140422239962</link><guid>http://making.meetup.com/post/140422239962</guid><pubDate>Thu, 03 Mar 2016 21:32:51 -0500</pubDate><category>engineering</category><category>offiste</category><dc:creator>lena-anne-meetup</dc:creator></item><item><title>Futurizing Meetup</title><description>&lt;p&gt;We believe in constantly futurizing Meetup, so we’ve been spending a lot of time prototyping, learning, and making as we move towards &lt;a href="http://making.meetup.com/post/139580873132/making-meetup-even-better" target="_blank"&gt;Rainbows &amp;amp; Unicorns and making Meetup even better&lt;/a&gt;. We hope that by sharing what we’re learning along the way, it helps other engineering teams positively change their company too.&lt;/p&gt;&lt;p&gt;Selecting the right tool for the job is core to our engineering culture. There are five big areas we’ve been focusing on so far, and with each one we’ve been building a little piece of Meetup product as the key part of our assessment.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Build, test, launch, test, build&amp;hellip;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;We&amp;rsquo;re rebuilding the backbone of Meetup &amp;ndash; our continuous delivery pipeline. We decided that in order to empower our engineers with the tools and infrastructure we have boldly envisioned, we’d need to use a new set of CI and automation tools and frameworks. We&amp;rsquo;re currently using &lt;a href="https://jenkins-ci.org/" target="_blank"&gt;Jenkins&lt;/a&gt; which has served us well, but really like what we&amp;rsquo;re seeing with &lt;a href="https://www.atlassian.com/software/bamboo/" target="_blank"&gt;Bamboo&lt;/a&gt; as a complete CI pipeline tool with very high quality plugins and orchestration hooks. &lt;/p&gt;&lt;p&gt;We&amp;rsquo;re reassessing our testing frameworks across our core, web, and mobile platforms so that we have a stronger suite of unit/integration/UI/regression tests with even more coverage.  So far we’ve been really enjoying using &lt;a href="http://www.seleniumhq.org/" target="_blank"&gt;Selenium&lt;/a&gt;, &lt;a href="http://appium.io/" target="_blank"&gt;Appium&lt;/a&gt; for our native apps, and the &lt;a href="http://robotframework.org/" target="_blank"&gt;Robot framework&lt;/a&gt; for acceptance testing.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Moving Meetup to the cloud&lt;/b&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;We&amp;rsquo;re a (mostly) bare metal shop with multiple data centers now. We’re ready to take advantage of the benefits of moving to the cloud including &lt;a href="https://cloud.google.com/compute/docs/autoscaler/" target="_blank"&gt;auto-scaling&lt;/a&gt;, the ability to create &lt;a href="https://en.wikipedia.org/wiki/Phoenix_(mythology)" target="_blank"&gt;phoenix systems&lt;/a&gt; with instances automatically rising out of ones that have crashed and burned, and reducing operational effort and total cost of ownership. &lt;/p&gt;&lt;p&gt;Our infrastructure team has been building our new continuous delivery pipeline and other tools on both &lt;a href="https://aws.amazon.com/" target="_blank"&gt;Amazon Web Services&lt;/a&gt; and &lt;a href="https://cloud.google.com/" target="_blank"&gt;Google Cloud Platform&lt;/a&gt; and we’re close to making a decisions as to which cloud provider we’re selecting.&lt;/p&gt;&lt;p&gt;&lt;b&gt;A world full of services&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Our core engineering team is breaking up our monolithic back-end platform into a service-oriented one.  We&amp;rsquo;re not yet sure how “micro-service” we&amp;rsquo;ll get since we&amp;rsquo;re still figuring out how &lt;a href="http://martinfowler.com/bliki/BoundedContext.html" target="_blank"&gt;bounded contexts&lt;/a&gt; apply to Meetup product, where the &lt;a href="https://www.informit.com/articles/article.aspx?p=359417&amp;amp;seqNum=3" target="_blank"&gt;seams&lt;/a&gt; really are in our codebase, and what parts of our monolith need to scale in bigger or different ways than the others.&lt;/p&gt;&lt;p&gt;We’re very excited to start on the path to learning and making decisions by building our first new service using part of &lt;a href="https://netflix.github.io/" target="_blank"&gt;the Netflix OSS stack&lt;/a&gt;. We did initial prototyping using &lt;a href="https://twitter.github.io/finagle/" target="_blank"&gt;Twitter’s Finagle&lt;/a&gt; and &lt;a href="https://www.typesafe.com/products/typesafe-reactive-platform" target="_blank"&gt;Typesafe’s Reactive Platform&lt;/a&gt; as well, and they’re all great stacks. But we’ve decided on the Netflix OSS and are starting off using &lt;a href="https://github.com/Netflix/hystrix" target="_blank"&gt;Hystrix&lt;/a&gt;, &lt;a href="https://github.com/ReactiveX/RxJava" target="_blank"&gt;RxJava&lt;/a&gt;, &lt;a href="https://github.com/ReactiveX/RxScala" target="_blank"&gt;RxScala&lt;/a&gt;, and &lt;a href="https://github.com/ReactiveX/RxNetty" target="_blank"&gt;RxNetty&lt;/a&gt; to build our first service.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Data is king&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Meetup has happily used &lt;a href="https://www.mysql.com/" target="_blank"&gt;MySQL &lt;/a&gt;as our primary data store for over a decade. Over the years we’ve added things like &lt;a href="http://hadoop.apache.org/" target="_blank"&gt;Hadoop&lt;/a&gt; for distributed computing and &lt;a href="https://aws.amazon.com/redshift/" target="_blank"&gt;Redshift&lt;/a&gt; for data warehousing. We’re at the right time in our growth to evaluate if other data store options will enable us to scale and perform better. We did a lot of research and prototyping with SQL, NoSQL, and distributed NoSQL data stores, and were inspired by the idea of &lt;a href="http://www.confluent.io/blog/turning-the-database-inside-out-with-apache-samza/" target="_blank"&gt;turning the database inside-out&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;We decided that we’d learn the most valuable information if we built our first new service using a NoSQL distributed data store like &lt;a href="http://cassandra.apache.org/" target="_blank"&gt;Apache Cassandra&lt;/a&gt;, &lt;a href="https://aws.amazon.com/dynamodb/" target="_blank"&gt;Amazon Dynamo&lt;/a&gt;, or &lt;a href="https://cloud.google.com/datastore/" target="_blank"&gt;Google Cloud Datastore&lt;/a&gt;, which we’re internally calling Cassandra* for short. Our decision on which one to use will align with our impending our cloud provider decision and until then we’re prototyping using Meetupy data with each.  &lt;/p&gt;&lt;p&gt;&lt;b&gt;React or not here we come&lt;/b&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Our web engineering team has been prototyping both &lt;a href="http://emberjs.com/" target="_blank"&gt;Ember&lt;/a&gt; and &lt;a href="https://facebook.github.io/react/" target="_blank"&gt;React&lt;/a&gt; by building a small part of Meetup web product with each. After that was done, and a lot of debate throughout the whole team, we’ve decided on React as our new JavaScript web framework.  &lt;/p&gt;&lt;p&gt;We’re super excited to be building an &lt;a href="http://isomorphic.net/" target="_blank"&gt;isomorphic JavaScript&lt;/a&gt; web stack to facilitate iterating web product in a faster and more productive way. We especially like the React ecosystem, separation of concerns, and preference for small, sharp tools.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Futurize Meetup with us&lt;/b&gt;&lt;/p&gt;&lt;p&gt;While we’ve answered many questions, we still have a long way to go.  We’re thrilled to work at a company where we have the time to prototype different technologies and build towards the best answers for both current and future Meetup product. As we progress, we&amp;rsquo;ll be writing posts that dive into the specifics of what we’re learning, the tools, technologies, and frameworks we&amp;rsquo;re using, and how they&amp;rsquo;re working for us.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you want to build the future of Meetup with us, learn and experiment with new technologies, or have ideas to share, check out ways to &lt;a href="http://www.meetup.com/jobs/" target="_blank"&gt;join our team&lt;/a&gt;. &lt;/p&gt;</description><link>http://making.meetup.com/post/140389877512</link><guid>http://making.meetup.com/post/140389877512</guid><pubDate>Thu, 03 Mar 2016 09:40:42 -0500</pubDate><category>infrastructure</category><category>cloud computing</category><category>microservices</category><category>tdd</category><category>testing</category><category>automation</category><category>javascript</category><category>continuous delivery</category><dc:creator>yvette-meetup</dc:creator></item><item><title>Hackathon!</title><description>&lt;p&gt;Last week, Meetup&amp;rsquo;s engineers took 48 hours off from their normal schedules in order to participate in our quarterly hackathon!&lt;/p&gt;

&lt;p&gt;The theme of this hackathon was &amp;lsquo;Rainbows and Unicorns&amp;rsquo;, in reference to our remaking of the Meetup platform that you can read about &lt;a href="http://making.meetup.com/post/139580873132/making-meetup-even-better" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check out some photos of the team in action:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://i.imgur.com/hWbM59s.jpg" alt="day1"/&gt;&lt;img src="https://i.imgur.com/jNaCyhC.jpg" alt="day2"/&gt;&lt;img src="https://i.imgur.com/SSPDVuv.jpg" alt="day3"/&gt;&lt;/p&gt;

&lt;p&gt;At the end of the 48 hours, we all demoed our projects, whether they were successful or not!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://imgur.com/li7MHE0.jpg" alt="demo"/&gt;&lt;/p&gt;

&lt;p&gt;And gave out these awesome Rainbows and Unicorns-themed prizes to the winners (yep, those are LED-lit horns):
&lt;img src="http://imgur.com/u5MKNjA.jpg" alt="prizes"/&gt;&lt;/p&gt;

&lt;hr&gt;&lt;p&gt;The winners were:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Most Ridiculous:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nathan Stilwell&lt;/strong&gt; - Magic Pipe
&lt;img src="https://i.imgur.com/y9DZjCq.jpg" alt="nathan"/&gt;&lt;/p&gt;

&lt;hr&gt;&lt;p&gt;&lt;em&gt;Most on theme:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evan Estola/Matt Kime&lt;/strong&gt; - Meetup on Alexa
&lt;img src="https://i.imgur.com/LLvlgtu.jpg" alt="evan"/&gt;&lt;/p&gt;

&lt;hr&gt;&lt;p&gt;&lt;em&gt;Best Overall:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rick Boenigk&lt;/strong&gt; - React Native Door Check
&lt;img src="https://i.imgur.com/elIo7xu.jpg" alt="rick"/&gt;&lt;/p&gt;

&lt;hr&gt;&lt;p&gt;We had our fair share of ridiculous hacks, as well as practical ones.  It was a lot of fun, and a lot of cool ideas came out of it.  Many of them might even get launched in some form or another!&lt;/p&gt;</description><link>http://making.meetup.com/post/139922861622</link><guid>http://making.meetup.com/post/139922861622</guid><pubDate>Wed, 24 Feb 2016 14:22:25 -0500</pubDate><category>meetup</category><category>hackathon</category><category>rainbows</category><category>unicorns</category><category>alexa</category><category>react</category><category>echo</category><dc:creator>jakemeetup</dc:creator></item><item><title>Making Meetup Even Better</title><description>&lt;p&gt;We&amp;rsquo;re always making Meetup better. For 14 years, we&amp;rsquo;ve been growing, evolving and making Meetup a little better every day, with every release. This year, we&amp;rsquo;ve kicked off one of the biggest endeavors in Meetup&amp;rsquo;s history to make Meetup even better. &lt;/p&gt;&lt;p&gt;We&amp;rsquo;re remaking the Meetup platform, infrastructure, and dev tools. Our objective is to empower our engineers to be more productive and love using our dev tools to make and ship product faster and better than ever before.&lt;/p&gt;&lt;p&gt;When we kicked this off, we did a lot of brainstorming, research, talking, listening, prototyping, and drew a &lt;i&gt;lot&lt;/i&gt; of diagrams. The very first diagram we drew and took a picture of was this (raw, not doctored) photo:&lt;/p&gt;&lt;figure data-orig-width="3264" data-orig-height="2448" class="tmblr-full"&gt;&lt;img src="http://68.media.tumblr.com/6f37289eb189aea4dc6906d8300cfa30/tumblr_inline_o2rx6oQDY31u0rkvc_540.jpg" alt="image" data-orig-width="3264" data-orig-height="2448"/&gt;&lt;/figure&gt;&lt;p&gt;What did we do when confronted with an unexpected rainbow shining right through our core platform as we drew up ways we’d re-architect it? Well, we of course named the remaking of Meetup the &lt;a href="https://www.google.com/search?q=rainbows+and+unicorns+project&amp;amp;espv=2&amp;amp;biw=1427&amp;amp;bih=778&amp;amp;source=lnms&amp;amp;tbm=isch&amp;amp;sa=X&amp;amp;ved=0ahUKEwjCwMiC7ILLAhUF8x4KHaw8BUYQ_AUIBigB&amp;amp;dpr=1#tbm=isch&amp;amp;q=rainbows+and+unicorns" target="_blank"&gt;&lt;i&gt;Rainbows &amp;amp; Unicorns&lt;/i&gt; &lt;/a&gt;project.&lt;/p&gt;&lt;p&gt;As we progress, we’ll be posting more specifics around what we’re prototyping, learning, and making as we move towards Rainbows &amp;amp; Unicorns. We hope that by sharing what we’re learning along the way, it helps others who might be doing something similar.&lt;/p&gt;&lt;p&gt;This week, we’re all busy with one of our quarterly &lt;a href="http://tmblr.co/ZnX14y21-7bqK" target="_blank"&gt;Meetup-wide hackathons&lt;/a&gt;, aptly themed: &lt;i&gt;Rainbows &amp;amp; Unicorns: futurizing Meetup&lt;/i&gt;. Stay tuned for more about what we’re hacking and making &amp;ndash; it’s guaranteed to be quite colorful and fun!&lt;/p&gt;</description><link>http://making.meetup.com/post/139580873132</link><guid>http://making.meetup.com/post/139580873132</guid><pubDate>Thu, 18 Feb 2016 22:47:16 -0500</pubDate><category>rainbows</category><category>unicorns</category><category>replatform</category><category>meetup</category><category>infrastructure</category><category>hackathon</category><dc:creator>yvette-meetup</dc:creator></item><item><title>hackathon progress pic.twitter.com/rXkm5FWkU0— Adam Detrick (@akdetrick) February 18, 2016
</title><description>&lt;blockquote class="twitter-tweet" data-lang="en"&gt;&lt;p lang="en" dir="ltr"&gt;hackathon progress &lt;a href="https://t.co/rXkm5FWkU0" target="_blank"&gt;pic.twitter.com/rXkm5FWkU0&lt;/a&gt;&lt;/p&gt;— Adam Detrick (@akdetrick) &lt;a href="https://twitter.com/akdetrick/status/700444364313645056" target="_blank"&gt;February 18, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src="//platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;</description><link>http://making.meetup.com/post/139571649812</link><guid>http://making.meetup.com/post/139571649812</guid><pubDate>Thu, 18 Feb 2016 19:43:34 -0500</pubDate><dc:creator>brianmeetup</dc:creator></item><item><title>Sorting Out Japanese</title><description>&lt;p&gt;&lt;img src="http://i.imgur.com/0eFkdmG.jpg" width="100%" alt="head"/&gt;&lt;/p&gt;

&lt;p&gt;For years, Meetup has been available in 6 different languages.  These are:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;English&lt;/li&gt;
&lt;li&gt;French&lt;/li&gt;
&lt;li&gt;German&lt;/li&gt;
&lt;li&gt;Italian&lt;/li&gt;
&lt;li&gt;Portuguese &lt;/li&gt;
&lt;li&gt;Spanish&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;And while these languages all have their own nuances and challenges when it comes to localizing for them, it was poor preparation for some of the issues we would run into when localizing for our next supported language&amp;hellip;&lt;/p&gt;

&lt;h2&gt;Japanese&lt;/h2&gt;

&lt;p&gt;Yes, that is right, Meetup is now available in it’s 7th supported language, Japanese!  It is our first supported language with a non-latin-based alphabet.&lt;/p&gt;

&lt;p&gt;We have run into many issues because of this, but the most interesting presented itself when it came time to implement alphabetical sorting.&lt;/p&gt;

&lt;h2&gt;Alphabetical Sorting&lt;/h2&gt;

&lt;p&gt;On first glance, alphabetically sorting a list of strings seems like a trivial task.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; Ordering
  .natural()
  .sortedCopy(["eagle","cat","dog","bird","falcon","duck"])
[bird, cat, dog, duck, eagle, falcon]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However many things can actually complicate this, such as capitalized letters:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; Ordering
  .natural()
  .sortedCopy(["eagle","cat","dog","bird","falcon","duck","Dog"])
[Dog, bird, cat, dog, duck, eagle, falcon]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A user would expect Dog and dog to be sorted next to each other.  However, because these strings are sorted by character code, this is not the case.&lt;/p&gt;

&lt;p&gt;To do a more language-friendly sort, you can use something called a collator.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; Ordering
  .from(Collator.getInstance(Locale.US))
  .sortedCopy(["eagle","cat","dog","bird","falcon","duck","Dog"])
[bird, cat, dog, Dog, duck, eagle, falcon]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This performs the sorting based on rules from the American English locale.
So how about Japanese?&lt;/p&gt;

&lt;h2&gt;Japanese Alphabets&lt;/h2&gt;

&lt;p&gt;The first thing to note is that there are multiple alphabets in play here:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Kanji: Thousands of symbols borrowed from Chinese and that can form words. Ex: 東京  - 東 means East and 京 means Capital city, so that’s Tokyo).&lt;/li&gt;
&lt;li&gt;Hiragana: Phonetic script (46 characters), for words that can not be described with Kanji, or to make the pronunciation of a word using kanji transparent. Each character corresponds to a sound, like ma, ka, sa…. Ex.: とうきょう  (To-ky-o)&lt;/li&gt;
&lt;li&gt;Katakana: Same as Hiragana (48 characters) but to represent the pronunciation of foreign words. Ex.: マクドナルド (ma-ku-do-na-ru-do, which is how the Japanese would pronounce McDonalds)&lt;/li&gt;
&lt;li&gt;Romaji: Latin characters, used to make the pronunciation of Japanese words transparent for those who can’t read the Japanese alphabets (ex: Tōkyō), or used to look trendy, foreign, in some cases. &lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Japanese ordering&lt;/h2&gt;

&lt;p&gt;Strings in Japanese can be made up of characters in any of these alphabets, and using ‘dumb’ sorting, these alphabets wouldn’t sort together at all.  However you can use a collator based on the Japanese locale, and that gets you pretty far already.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;健康 (Health)&lt;/li&gt;
&lt;li&gt;ダンス (Dancing)&lt;/li&gt;
&lt;li&gt;テクノロジー (Tech)&lt;/li&gt;
&lt;li&gt;家族 (Family)&lt;/li&gt;
&lt;li&gt;ゲーム (Games)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Once sorted with the collator, it becomes:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;ゲーム (Games)&lt;/li&gt;
&lt;li&gt;ダンス (Dancing)&lt;/li&gt;
&lt;li&gt;テクノロジー (Tech)&lt;/li&gt;
&lt;li&gt;健康 (Health)&lt;/li&gt;
&lt;li&gt;家族 (Family)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;See Below:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;x = [u”健康”, u”ダンス”, u”テクノロジー”, u”家族”, u”ゲーム”]
&amp;gt;&amp;gt;&amp;gt; Ordering
  .from(Collator.getInstance(Locale.JAPAN))
  .sortedCopy(x)
[ゲーム, ダンス, テクノロジー, 家族, 健康]
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;The problem&lt;/h2&gt;

&lt;p&gt;This will sort words starting with Katakana and Hiragana correctly, but will always put the words starting with a Kanji at the bottom of the list. 
Why? Because a computer does not know how a Kanji is pronounced, and ordering in Japanese is based on pronunciation, following the strict Gojūon (literally, “fifty sounds”) ordering table for kana alphabets. First should come the words starting with the sound a then with i, u, e, ka, ki, ku, etc.). 
With Kanji, the characters used do not each correspond to the same sound every time. The pronunciation changes depending on context, and currently computers can not guess that.&lt;/p&gt;

&lt;p&gt;Ex.: 今日 can be read as きょう (kyō) or こんにち (konnichi).&lt;/p&gt;

&lt;h2&gt;The solution&lt;/h2&gt;

&lt;p&gt;Given a large list of arbitrary kanji strings, we would be unable to sort them correctly without human intervention giving us an indication of how it’s pronounced in its context.  But luckily for us, we don’t have a large list of arbitrary strings! We have a relatively small list of static, already known strings.  So we did in fact have a solution.&lt;br/&gt;
The thing we needed to sort was the list of categories that Meetup Groups can belong to. We just needed the phonetic spellings of our categories which had Kanji-based names, as we learned earlier that any Kanji-based name can be converted into a more transparent phonetic version.&lt;/p&gt;

&lt;p&gt;We asked our translators to help provide these, and then created a new locale called ‘Japanese Phonetic&amp;rsquo; (ja-x-phonetic) and a new translation file containing these phonetic translations.  And then, when ordering the list on the backend, we temporarily translated the categories into ja-x-phonetic, sorted them using a Japanese collator, and then re-translated them back into normal Japanese while maintaining the same order. Et Voilà!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/hgto7pr.png" width="100%" alt="cat"/&gt;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;So we solved our problem, but this is an issue which continues to exist for things like user generated content.  If we had a large list of member names in Kanji that we wanted to sort, this would be impossible to do without either transliterating each of these ourselves (not scalable), or prompting users to provide phonetic spellings of their names in addition to the Kanji one (more scalable).&lt;/p&gt;

&lt;p&gt;This issue came up unexpectedly, but taught us a good lesson about not making any assumptions when dealing with language.  If you want to develop a global product, you have to deal with your product in a global way, and that means building things that make sense in ALL languages.&lt;/p&gt;</description><link>http://making.meetup.com/post/131750615312</link><guid>http://making.meetup.com/post/131750615312</guid><pubDate>Fri, 23 Oct 2015 11:11:05 -0400</pubDate><category>meetup</category><category>japan</category><category>japanese</category><category>internationalization</category><category>sorting</category><dc:creator>jakemeetup</dc:creator></item><item><title>Meetup and Slack</title><description>&lt;p&gt;Meetup recently made the switch to &lt;a href="https://slack.com/" target="_blank"&gt;Slack&lt;/a&gt; for our team communication platform and our clearinghouse of puppy gifs. One of my favorite features on Slack is how incredibly easy it is to create &lt;a href="https://slack.com/integrations" target="_blank"&gt;integrations&lt;/a&gt;. In order to get familiar with how the webhook system works, I decided to write a little ruby app that uses the &lt;a href="http://www.meetup.com/meetup_api/" target="_blank"&gt;Meetup API&lt;/a&gt; to post the next available Meetup event for a given group. If you are an organizer who is using a Slack team to facilitate conversation outside of your Meetup events, host Meetups in your office, or just want to let your coworkers know when something interesting is happening, this might come in handy. Enjoy!&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/jeffcampbell/meetup-slack" target="_blank"&gt;https://github.com/jeffcampbell/meetup-slack&lt;/a&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;Jeff is a Senior QA Engineer at Meetup&lt;/i&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/130161038177</link><guid>http://making.meetup.com/post/130161038177</guid><pubDate>Tue, 29 Sep 2015 18:47:48 -0400</pubDate><category>Meetup</category><category>Slack</category><dc:creator>meetupjeff</dc:creator></item><item><title>Apple In-App Purchase Mock Service (Fake it ‘till you make it)</title><description>&lt;p&gt;&lt;b&gt;A configurable sandbox to test auto-renewing Apple IAP subscriptions&lt;/b&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;TLDR;&lt;/b&gt; We made a thing that pretends to be an Apple In-App Purchase service to make it easier for people to test their code. It’s open sourced and can be found here: &lt;a href="https://github.com/meetup/apple-of-my-iap" target="_blank"&gt;https://github.com/meetup/apple-of-my-iap&lt;/a&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;The long story:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;As part of Meetup’s iOS offering, we recently launched the ability for our members to use Apple In-App purchases (IAP) when buying Meetup subscriptions.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Implementing this feature was a lot of fun. The same kind of fun as running through a gauntlet full of sharp axes, hot flames, and killer piranhas.&lt;/b&gt;&lt;/p&gt;&lt;figure class="tmblr-full" data-orig-height="281" data-orig-width="500"&gt;&lt;img src="http://68.media.tumblr.com/8bb40c29111d11d8ffc48aedcb966cba/tumblr_inline_ntr31mpVyT1r7wad1_500.gif" data-orig-height="281" data-orig-width="500"/&gt;&lt;/figure&gt;&lt;p&gt;But before we get into that…. &lt;br/&gt;&lt;/p&gt;&lt;h2&gt;&lt;b&gt;What exactly is an Apple In-App Purchase, and more importantly why do I care? (Hint: It’s not Apple Pay)&lt;/b&gt;&lt;/h2&gt;&lt;p&gt;An Apple In-App Purchase (IAP) is a purchase of digital goods or services through Apple’s native payment processing platform available on all iOS devices. If you’re an iOS user and you’ve ever been prompted by this screen: &lt;/p&gt;&lt;figure class="tmblr-full" data-orig-height="480" data-orig-width="320"&gt;&lt;img src="http://68.media.tumblr.com/07359037da2b2b478765a800e1a45cac/tumblr_inline_ntr31ysTiP1r7wad1_540.png" data-orig-height="480" data-orig-width="320"/&gt;&lt;/figure&gt;&lt;p&gt;then chances are you’ve made an In-App Purchase before. Typical use cases of include:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;unlocking premium features within an application&lt;/li&gt;&lt;li&gt;purchasing extra levels or items from within a game&lt;/li&gt;&lt;li&gt;purchasing a subscription to digital content&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Since a customer’s payment information is already stored in their iTunes account, they have the ability to make quick and painless payments without having to pull out their wallet and re-enter credit card number information. One tap and they’re done. This also means that you don’t have to spend time designing, building, and maintaining finicky payment forms. &lt;/p&gt;&lt;p&gt;And if that’s not enough incentive for you, Apple will kick you out of the iTunes store for attempting to sell digital goods/services in any other manner other than through IAP.&lt;/p&gt;&lt;figure class="tmblr-full" data-orig-height="211" data-orig-width="320"&gt;&lt;img src="http://68.media.tumblr.com/80c9d177ffda40e3e2d3a3e2cbd02786/tumblr_inline_ntr32tCaX11r7wad1_500.gif" data-orig-height="211" data-orig-width="320"/&gt;&lt;/figure&gt;&lt;p&gt;Sounds like a deal to me.&lt;/p&gt;&lt;h2&gt;&lt;b&gt;Meetup meets IAP&lt;/b&gt;&lt;/h2&gt;&lt;p&gt;Here at Meetup, we elected to use the auto-renewing feature of Apple IAP, which means that Apple will automagically take care of all the nonsense that comes with scheduling and charging subscription payments. Hooray!&lt;br/&gt;&lt;/p&gt;&lt;p&gt;All we have to do is ask Apple who paid for what, and then ensure that we are delivering the right service and products to the right people. Since the Meetup platform exists on the web as well as on both iOS and Android, we delegate subscription management to the server in order to ensure a uniform experience across all 3 platforms. &lt;br/&gt;&lt;/p&gt;&lt;p&gt;So for any given member with a Meetup subscription bought through IAP, we query Apple’s iTunes endpoint and receive a response similar to this:&lt;br/&gt;&lt;/p&gt;&lt;p&gt;{&lt;br/&gt;    &amp;quot;status&amp;quot;: 0,&lt;br/&gt;    &amp;quot;environment&amp;quot;: &amp;ldquo;Sandbox&amp;rdquo;,&lt;br/&gt;    &amp;quot;receipt&amp;quot;: {&lt;br/&gt;        &amp;quot;receiptType&amp;quot;: &amp;ldquo;ProductionSandbox&amp;rdquo;,&lt;br/&gt;        &amp;quot;adamId&amp;quot;: 0,&lt;br/&gt;        &amp;quot;appItemId&amp;quot;: 0,&lt;br/&gt;        &amp;quot;bundleId&amp;quot;: &amp;ldquo;com.meetup.iphone&amp;rdquo;,&lt;br/&gt;        &amp;quot;applicationVersion&amp;quot;: &amp;ldquo;409000&amp;rdquo;,&lt;br/&gt;        &amp;quot;downloadId&amp;quot;: 0,&lt;br/&gt;        &amp;quot;versionExternalIdentifier&amp;quot;: 0,&lt;br/&gt;        &amp;quot;requestDate&amp;quot;: &amp;ldquo;2015-04-23 23:33:34 Etc/GMT&amp;rdquo;,&lt;br/&gt;        &amp;quot;requestDateMs&amp;quot;: &amp;ldquo;1429832014510&amp;rdquo;,&lt;br/&gt;        &amp;quot;requestDatePst&amp;quot;: &amp;ldquo;2015-04-23 16:33:34 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;        &amp;quot;originalPurchaseDate&amp;quot;: &amp;ldquo;2013-08-01 07:00:00 Etc/GMT&amp;rdquo;,&lt;br/&gt;        &amp;quot;originalPurchaseDateMs&amp;quot;: &amp;ldquo;1375340400000&amp;rdquo;,&lt;br/&gt;        &amp;quot;originalPurchaseDatePst&amp;quot;: &amp;ldquo;2013-08-01 00:00:00 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;        &amp;quot;originalApplicationVersion&amp;quot;: &amp;ldquo;1.0&amp;rdquo;,&lt;br/&gt;        &amp;quot;inApp&amp;quot;: [&lt;br/&gt;            {&lt;br/&gt;                &amp;quot;quantity&amp;quot;: &amp;ldquo;1&amp;rdquo;,&lt;br/&gt;                &amp;quot;productId&amp;quot;: &amp;ldquo;com.meetup.iphone.test.7days&amp;rdquo;,&lt;br/&gt;                &amp;quot;transactionId&amp;quot;: &amp;ldquo;1000000151887289&amp;rdquo;,&lt;br/&gt;                &amp;quot;originalTransactionId&amp;quot;: &amp;ldquo;1000000151887289&amp;rdquo;,&lt;br/&gt;                &amp;quot;purchaseDate&amp;quot;: &amp;ldquo;2015-04-15 21:46:04 Etc/GMT&amp;rdquo;,&lt;br/&gt;                &amp;quot;purchaseDateMs&amp;quot;: &amp;ldquo;1429134364000&amp;rdquo;,&lt;br/&gt;                &amp;quot;purchaseDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:46:04 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;                &amp;quot;originalPurchaseDate&amp;quot;: &amp;ldquo;2015-04-15 21:46:06 Etc/GMT&amp;rdquo;,&lt;br/&gt;                &amp;quot;originalPurchaseDateMs&amp;quot;: &amp;ldquo;1429134366000&amp;rdquo;,&lt;br/&gt;                &amp;quot;originalPurchaseDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:46:06 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;                &amp;quot;expiresDate&amp;quot;: &amp;ldquo;2015-04-15 21:49:04 Etc/GMT&amp;rdquo;,&lt;br/&gt;                &amp;quot;expiresDateMs&amp;quot;: &amp;ldquo;1429134544000&amp;rdquo;,&lt;br/&gt;                &amp;quot;expiresDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:49:04 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;                &amp;quot;webOrderLineItemId&amp;quot;: &amp;ldquo;1000000029487694&amp;rdquo;,&lt;br/&gt;                &amp;quot;isTrialPeriod&amp;quot;: &amp;ldquo;false&amp;rdquo;&lt;br/&gt;            },&lt;br/&gt;            {&lt;br/&gt;                &amp;quot;quantity&amp;quot;: &amp;ldquo;1&amp;rdquo;,&lt;br/&gt;                &amp;quot;productId&amp;quot;: &amp;ldquo;com.meetup.iphone.test.7days&amp;rdquo;,&lt;br/&gt;                &amp;quot;transactionId&amp;quot;: &amp;ldquo;1000000151887546&amp;rdquo;,&lt;br/&gt;                &amp;quot;originalTransactionId&amp;quot;: &amp;ldquo;1000000151887289&amp;rdquo;,&lt;br/&gt;                &amp;quot;purchaseDate&amp;quot;: &amp;ldquo;2015-04-15 21:49:04 Etc/GMT&amp;rdquo;,&lt;br/&gt;                &amp;quot;purchaseDateMs&amp;quot;: &amp;ldquo;1429134544000&amp;rdquo;,&lt;br/&gt;                &amp;quot;purchaseDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:49:04 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;                &amp;quot;originalPurchaseDate&amp;quot;: &amp;ldquo;2015-04-15 21:48:06 Etc/GMT&amp;rdquo;,&lt;br/&gt;                &amp;quot;originalPurchaseDateMs&amp;quot;: &amp;ldquo;1429134486000&amp;rdquo;,&lt;br/&gt;                &amp;quot;originalPurchaseDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:48:06 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;                &amp;quot;expiresDate&amp;quot;: &amp;ldquo;2015-04-15 21:52:04 Etc/GMT&amp;rdquo;,&lt;br/&gt;                &amp;quot;expiresDateMs&amp;quot;: &amp;ldquo;1429134724000&amp;rdquo;,&lt;br/&gt;                &amp;quot;expiresDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:52:04 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;                &amp;quot;webOrderLineItemId&amp;quot;: &amp;ldquo;1000000029487695&amp;rdquo;,&lt;br/&gt;                &amp;quot;isTrialPeriod&amp;quot;: &amp;ldquo;false&amp;rdquo;&lt;br/&gt;            }&lt;br/&gt;        ]&lt;br/&gt;    },&lt;br/&gt;    &amp;quot;latestReceiptInfo&amp;quot;: [&lt;br/&gt;        {&lt;br/&gt;            &amp;quot;quantity&amp;quot;: &amp;ldquo;1&amp;rdquo;,&lt;br/&gt;            &amp;quot;productId&amp;quot;: &amp;ldquo;com.meetup.iphone.test.7days&amp;rdquo;,&lt;br/&gt;            &amp;quot;transactionId&amp;quot;: &amp;ldquo;1000000151887289&amp;rdquo;,&lt;br/&gt;            &amp;quot;originalTransactionId&amp;quot;: &amp;ldquo;1000000151887289&amp;rdquo;,&lt;br/&gt;            &amp;quot;purchaseDate&amp;quot;: &amp;ldquo;2015-04-15 21:46:04 Etc/GMT&amp;rdquo;,&lt;br/&gt;            &amp;quot;purchaseDateMs&amp;quot;: &amp;ldquo;1429134364000&amp;rdquo;,&lt;br/&gt;            &amp;quot;purchaseDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:46:04 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;            &amp;quot;originalPurchaseDate&amp;quot;: &amp;ldquo;2015-04-15 21:46:06 Etc/GMT&amp;rdquo;,&lt;br/&gt;            &amp;quot;originalPurchaseDateMs&amp;quot;: &amp;ldquo;1429134366000&amp;rdquo;,&lt;br/&gt;            &amp;quot;originalPurchaseDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:46:06 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;            &amp;quot;expiresDate&amp;quot;: &amp;ldquo;2015-04-15 21:49:04 Etc/GMT&amp;rdquo;,&lt;br/&gt;            &amp;quot;expiresDateMs&amp;quot;: &amp;ldquo;1429134544000&amp;rdquo;,&lt;br/&gt;            &amp;quot;expiresDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:49:04 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;            &amp;quot;webOrderLineItemId&amp;quot;: &amp;ldquo;1000000029487694&amp;rdquo;,&lt;br/&gt;            &amp;quot;isTrialPeriod&amp;quot;: &amp;ldquo;false&amp;rdquo;&lt;br/&gt;        },&lt;br/&gt;        {&lt;br/&gt;            &amp;quot;quantity&amp;quot;: &amp;ldquo;1&amp;rdquo;,&lt;br/&gt;            &amp;quot;productId&amp;quot;: &amp;ldquo;com.meetup.iphone.test.7days&amp;rdquo;,&lt;br/&gt;            &amp;quot;transactionId&amp;quot;: &amp;ldquo;1000000151887546&amp;rdquo;,&lt;br/&gt;            &amp;quot;originalTransactionId&amp;quot;: &amp;ldquo;1000000151887289&amp;rdquo;,&lt;br/&gt;            &amp;quot;purchaseDate&amp;quot;: &amp;ldquo;2015-04-15 21:49:04 Etc/GMT&amp;rdquo;,&lt;br/&gt;            &amp;quot;purchaseDateMs&amp;quot;: &amp;ldquo;1429134544000&amp;rdquo;,&lt;br/&gt;            &amp;quot;purchaseDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:49:04 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;            &amp;quot;originalPurchaseDate&amp;quot;: &amp;ldquo;2015-04-15 21:48:06 Etc/GMT&amp;rdquo;,&lt;br/&gt;            &amp;quot;originalPurchaseDateMs&amp;quot;: &amp;ldquo;1429134486000&amp;rdquo;,&lt;br/&gt;            &amp;quot;originalPurchaseDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:48:06 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;            &amp;quot;expiresDate&amp;quot;: &amp;ldquo;2015-04-15 21:52:04 Etc/GMT&amp;rdquo;,&lt;br/&gt;            &amp;quot;expiresDateMs&amp;quot;: &amp;ldquo;1429134724000&amp;rdquo;,&lt;br/&gt;            &amp;quot;expiresDatePst&amp;quot;: &amp;ldquo;2015-04-15 14:52:04 America/Los_Angeles&amp;rdquo;,&lt;br/&gt;            &amp;quot;webOrderLineItemId&amp;quot;: &amp;ldquo;1000000029487695&amp;rdquo;,&lt;br/&gt;            &amp;quot;isTrialPeriod&amp;quot;: &amp;ldquo;false&amp;rdquo;&lt;br/&gt;        }&lt;br/&gt;    ],&lt;br/&gt;    &amp;quot;latestReceipt&amp;quot;: &amp;ldquo;MIJA5AYJKoZIhvcNAQcCoIJA1TCCQNECAQEx &amp;hellip;&amp;rdquo;&lt;br/&gt;}&lt;/p&gt;&lt;h2&gt;&lt;b&gt;The Problem: Testing with IAP&lt;/b&gt;&lt;/h2&gt;&lt;p&gt;Apple provides an iTunes sandbox environment which can be used to test In-App Purchases without spending real money. For auto-renewing subscriptions, the sandbox environment allows you to create a subscription which then automatically renew itself six times before expiring. Since many subscriptions periods last one week at the very least, Apple provides shorter test durations for the sandbox environment which are mapped to production durations in the following manner:&lt;/p&gt;&lt;p&gt;&lt;b&gt;Production -&amp;gt; Sandbox&lt;/b&gt;&lt;/p&gt;&lt;p&gt;1 week        -&amp;gt;  3 minutes&lt;br/&gt;&lt;/p&gt;&lt;p&gt;1 month      -&amp;gt;  5 minutes&lt;/p&gt;&lt;p&gt;2 months    -&amp;gt;  10 minutes&lt;/p&gt;&lt;p&gt;3 months    -&amp;gt;  15 minutes&lt;/p&gt;&lt;p&gt;6 months    -&amp;gt;  30 minutes&lt;/p&gt;&lt;p&gt;1 year         -&amp;gt;  1 hour&lt;/p&gt;&lt;p&gt;However, there were some serious limitations with the iTunes sandbox which made it difficult to develop and test for, especially for non-iOS engineers like myself. &lt;br/&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;You need to have an iOS device with IAP functionality already built into your app in order to simulate an IAP purchase. This would require our iOS engineers to try and build IAP functionality into the app before any backend support for it existed.&lt;br/&gt;&lt;/li&gt;&lt;li&gt;It’s impossible to manipulate test subscriptions once they have been created in the sandbox. Testing edge cases such as refunds, cancellations, early renewals, late renewals, etc. are only doable by writing mock subscription creation cases within the iOS app. This would require our iOS engineers to spend extra time creating tooling around a feature that they couldn’t yet test. &lt;br/&gt;&lt;/li&gt;&lt;li&gt;The shortest amount of time it takes for a subscription to expire is 18 minutes, which is particularly irritating when you’re trying to debug expiration logic in your application.&lt;br/&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Points #1 and #2 would have created heavy inter-team dependencies between our iOS engineers and our backend engineers, something which would have slowed down development immensely.&lt;/p&gt;&lt;p&gt;Point #3 is just annoying. &lt;br/&gt;&lt;/p&gt;&lt;p&gt;Unable to get what we wanted from Apple’s iTunes sandbox environment, we decided to roll our own mock service which simulates IAP subscriptions. Our requirements were pretty straightforward. We wanted a service that:&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;would mimic responses we’d receive from the iTunes store&lt;/li&gt;&lt;li&gt;was isolated from our codebase and behave as a 3rd party service&lt;/li&gt;&lt;li&gt;could simulate IAP transactions without an iOS device&lt;/li&gt;&lt;li&gt;could simulate different IAP subscriptions states (refunded, cancelled, etc.)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;So we built it!&lt;/p&gt;&lt;p&gt;The end result is a service that any of our engineers could spin up at a moment’s notice, create mock subscriptions, test weird edge cases, and then shut it all down with a few keystrokes. &lt;br/&gt;&lt;/p&gt;&lt;p&gt;If you’re interested in trying out our service, simply grab the code from our github repo: &lt;a href="https://github.com/meetup/apple-of-my-iap" target="_blank"&gt;https://github.com/meetup/apple-of-my-iap&lt;/a&gt; and take it for a spin!&lt;/p&gt;&lt;figure class="tmblr-full" data-orig-height="300" data-orig-width="400"&gt;&lt;img src="http://68.media.tumblr.com/2e811dd69377aef7d5b4fa27c00577bb/tumblr_inline_ntr339lDy61r7wad1_500.gif" data-orig-height="300" data-orig-width="400"/&gt;&lt;/figure&gt;</description><link>http://making.meetup.com/post/127718510507</link><guid>http://making.meetup.com/post/127718510507</guid><pubDate>Thu, 27 Aug 2015 11:48:01 -0400</pubDate><dc:creator>confoundead</dc:creator></item><item><title>All future support tickets to be written in iambic pentameter</title><description>&lt;p&gt;Senior Machine Learning Engineer &lt;a href="https://twitter.com/estola" target="_blank"&gt;Evan Estola&lt;/a&gt; recently filed a support ticket&amp;hellip; in iambic pentameter. Our systems team promptly upgraded his workstation.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;It is in the nature of my job here, that my poor dev box is frequently down,
overloaded as it were by process - whom by their own nature and not of fault,
are very intensive of memory.

I enjoy engaging primarily - in the habit of a linux machine, and because I
sometimes do rely on (e.g. data which I need to spy on) complex data
visualizations, a racked machine would be less than ideal.

Therefore the idyllic setup for me (and lo I know that this demand be bold, and
understand if it unlikely be); a workstation under my desk as now,
but with 64G of memory.
&lt;/code&gt;&lt;/pre&gt;</description><link>http://making.meetup.com/post/125928516185</link><guid>http://making.meetup.com/post/125928516185</guid><pubDate>Wed, 05 Aug 2015 10:00:10 -0400</pubDate><category>iambic pentameter</category><category>software</category><category>meetup</category><category>bigdata</category><dc:creator>adrianparsons</dc:creator></item><item><title>Python 2.x and Unicode: A Story of Love and (almost) Murder</title><description>&lt;p&gt;&lt;em&gt;by Anne DeCusatis, Core Engineer on Meetup&amp;rsquo;s International/Partnerships team&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I love working
with Unicode. It&amp;rsquo;s fascinating how we&amp;rsquo;ve designed complex ways to represent something as simple and fundamental
as characters. It also allows us to support the incredible diversity in languages of computer users. It appeals to my
engineering brain as an interesting problem and to my more emotional
side, since having Unicode support helps people express themselves on
our platform.&lt;/p&gt;

&lt;p&gt;Recently,
I worked on a bug that attempted to change my warm-and-fuzzy Unicode
feelings.&lt;/p&gt;

&lt;p&gt;At
Meetup Engineering, we use a Python script to push our code into
review. This script integrates with both Github Enterprise and Bugzilla. Recently, one of our engineers added
support to this script to pull the bug title and description from
Bugzilla into the Python script. The title and description can then be approved or edited by the
developer and sent to Github. This was a great improvement,
since copy/pasting the bug description every time was tedious and
multi-line descriptions weren&amp;rsquo;t handled well when pasting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What&amp;rsquo;s
the problem here?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ll
give you a hint: Python 2.x has a &lt;a href="https://docs.python.org/2/howto/unicode.html" target="_blank"&gt;surprisingly lengthy page&lt;/a&gt;
in its documentation describing how Unicode string/byte string conversions work. I found
it to be a fun read,
the first time! The tenth time, not so much.&lt;/p&gt;

&lt;p&gt;Specifically,
our problem was:&lt;/p&gt;

&lt;p&gt;Non-ASCII
Unicode characters in Bugzilla titles and descriptions were (1) not displaying properly in the terminal and (2) throwing a
UnicodeDecodeError when we tried to dump them into a JSON string to
send in an HTTP request to Github Enterprise.&lt;/p&gt;

&lt;p&gt;This
seemed pretty simple to me, since I knew that Python&amp;rsquo;s json.dumps has
a parameter you can pass in to create a Unicode string instead of a
byte string, so I agreed to take this bug on. “Python
is fun, and Unicode is interesting,” I thought. “This will
probably take about an hour, at most, and then everyone will give me
credit for having improved our dev process immeasurably, and I will
ride a wave of admiration into the sunset.”&lt;/p&gt;

&lt;p&gt;After
a day or two of messing with it, frustrated with Unicode,
Python, and myself, I worked on other projects until I was again
feeling up to the challenge. This brings us to the present day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The
solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A
non-Unicode tip I learned working on this: there are diminishing returns after 6pm on a Friday. Go home and look at it
Monday morning – it&amp;rsquo;s likely you&amp;rsquo;ll get the same amount of progress as continuing to work several more hours.&lt;/p&gt;

&lt;p&gt;I digress. There
were two parts to the problem: the incorrect display of characters,
and the UnicodeDecodeError when sending them out.&lt;/p&gt;

&lt;p&gt;The
incorrect display of characters was caused because, as I found, the
byte string from our MySQL Bugzilla database was not in
the format expected of a byte string by Python. To explain this, let&amp;rsquo;s go into a little detail about strings in Python, and about how a computer stores characters.&lt;/p&gt;

&lt;p&gt;Python 2.x stores two kinds of strings: Unicode strings and byte strings. Byte strings are meant to hold ASCII characters, which always take up one byte, and can be coerced into holding other Unicode characters. Python reads and displays byte strings one byte at a time. This is bad for displaying Unicode because Unicode characters may take up more than one byte per character. Unicode strings, on the other hand, are more suitable for printing Unicode characters, since Python knows that one byte of a Unicode string might not be one character. The conversion between these types of strings is supposed to be relatively seamless.
I found that the character I was
testing with, »
(RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK), was represented
in the byte string that came from our Bugzilla database as “\xbb”, whereas a new string created with »
would be encoded as “\xc2\xbb”. This meant that I would see a question mark block (�, the computer-universal symbol for &amp;ldquo;I don&amp;rsquo;t know what this character is&amp;rdquo;) when printing the string instead of a right guillemet.&lt;/p&gt;

&lt;p&gt;To solve this, I took a round
trip. Character by character, I called &lt;code&gt;unichr(ord( c )).encode(“utf-8”)&lt;/code&gt;. In Python, &lt;code&gt;ord()&lt;/code&gt; returns the
value of a character, and &lt;code&gt;unichr()&lt;/code&gt; returns the character from a
value. Since I wanted to print a Unicode string, I also called
&lt;code&gt;.decode(“utf-8”)&lt;/code&gt; on it. My code eventually looked like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#A workaround for 47510
def bugz_unicode(bugz_output_string):
    return u"".join([process_char(c) for c in bugz_output_string])

def process_char(c):
   return unichr(ord(c)).encode("utf-8").decode("utf-8")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What
can I say? It does the job.&lt;/p&gt;

&lt;p&gt;Great,
now I can dump a JSON string, right? Well, not exactly. It turns out,
urllib2 (with which we were sending the HTTP request to our Github
Enterprise instance) only takes byte strings, and I just went through
a lot of work to ensure I had a Unicode string.&lt;/p&gt;

&lt;p&gt;This
was solved by calling &lt;code&gt;.encode(”utf-8″)&lt;/code&gt; again, once I figured out that was what
I needed to do&amp;hellip;
&lt;img src="http://68.media.tumblr.com/8d438559d5917309caa5d205176b3d09/tumblr_inline_ns7wseP5Gl1tzbr9n_540.png" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;One
more note: I could only test this when my working directory was clean
of changes, because the script prevents you from pushing to git if
you haven&amp;rsquo;t committed yet. This led to some fun commit logs:
&lt;img src="http://68.media.tumblr.com/a61cd8f747d5d8a1cbb039eb92b8862e/tumblr_inline_ns7wtlnwBo1tzbr9n_540.png" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Eventually,
though, it got merged, and is now launched and propagating its way to
all the other developers&amp;rsquo; environments.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://68.media.tumblr.com/a1c3fd8b102f3d38ccb4a708f1b873d9/tumblr_inline_ns7wuuWXNK1tzbr9n_540.png" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Note
that there were, in the end, 45 commits, but only 20 lines changed.
In other words: I wrote over twice as many lines &lt;strong&gt;about&lt;/strong&gt;
the problem as I did &lt;strong&gt;to fix&lt;/strong&gt;
the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In
conclusion&amp;hellip;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1.
Python 2.x + Unicode = CAUTION&lt;/p&gt;

&lt;p&gt;2.
We use &lt;a href="https://en.wikipedia.org/wiki/Jython" target="_blank"&gt;Jython&lt;/a&gt;, so we&amp;rsquo;ll likely be on Python 2.x
for a while.&lt;/p&gt;

&lt;p&gt;3.
I still love Unicode, and I still love Python. But I no longer feel
that they could be two great tastes that taste great together.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://68.media.tumblr.com/ad3ab386d2aa31b37b3c4cd3dc7763d1/tumblr_inline_ns975hk0x41tzbr9n_540.png" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/honest_update/status/625659846285627392" target="_blank"&gt;via https://twitter.com/honest_update/status/625659846285627392&lt;/a&gt;&lt;/p&gt;</description><link>http://making.meetup.com/post/125429906409</link><guid>http://making.meetup.com/post/125429906409</guid><pubDate>Thu, 30 Jul 2015 10:00:13 -0400</pubDate><category>python</category><category>unicode</category><dc:creator>anne-meetup</dc:creator></item></channel></rss>
