Everyone at JUST EAT works to empower consumers to love their takeaway experience and from our start in 2001 technology has played a critical role in our growth and success. As an Engineering group we like lean and agile, but we’re not dogmatic about it, we want to build great software that does its job and nothing more, and we maintain a mixture of old and new, greenfield and brownfield on a daily basis. We use the best tools for the job – we’re a polyglot environment and you’ll find a predominantly Microsoft stack, augmented with the best of open source.
As we grow, we want to maintain a focus on quality while rapidly delivering great features to support our growth. It’s your talent and ideas that will help us do that. So hopefully after reading more about how the people in Engineering at JUST EAT work and build great software together you’ll want to come and join us too.
Your first day
You’ve done the interviews, technical tests and contracts and you’re finally here – firstly, congratulations! Welcome to the team. We’re happy you’re here and want to help you acclimatise.
Firstly, we’re engineering heavy. That means there are a lot of faces to meet, so chances are for your first day, you’re going to be spending time with your team. You’ll be given a computer that you’re going to want to take some time setting up. The tools you’ll need vary from team to team but you’ll find some hints regarding useful configurations on the wiki.
Every member of the Engineering team is responsible for:
- The availability, security, scalability of our e-commerce platform
- Delivering our product roadmap
- Planning for the future
Our principles are at the core of how we meet our responsibilities. As a member of the Engineering team at JUST EAT, you’ll need to demonstrate those principles and make them a core part of how you work day to day:
- Do the right thing
- Take responsibility
- Be transparent
- Continuously improve
- Take pride
As part of being responsible humans, there are a few web-based compliance course you’ll have to take. Don’t worry, they shouldn’t take more than an hour and are both humorous and informative, so it’s best to get them out of the way at this point. You’ll learn how not to accept a bribe (pro-tip: don’t accept bribes!) and how to make sure you’re not exposing the company to liability. The office administration staff will send you all the links and credentials you need for these courses.
Your first week
Like any job, your first week is going to be a sea of faces with names you can’t remember and an overwhelming amount of information to absorb – so first, don’t panic!
You’re going to want to get up to speed on the technology stack and tool choices of the team you’re working in. Hopefully, having past the interview, you’ll already have a bunch of that stuff down, but like all organisations, the usage of technology frequently varies, so you’re going to want to understand the conventions and house styles of our code. Broadly, our coding standards are set out in the wiki but it’s important realise that we are aiming for “internal consistency” in the code-base.
What this means is that each application and team may have its own house style, derived from the more general guidance. During your first week, you should expect to spend most of your time pairing with other people on your team, learning the ropes, and getting elbow deep in the codebase.
Towards the end of your first week and the start of your second, find time to pair with people on other teams that you work with (e.g. if you’re on consumer web apps, take the time to spend half a day pairing with people on the API teams) – the more teams you spend time with, the better – it’ll give you a holistic view of the things we’re working on at the time. While you’re pairing, make sure you ask questions – anything that isn’t obvious is probably something we should improve anyway, so don’t worry, it’s encouraged.
We have 12 teams in Engineering (you’ll be able to put faces to names with the org chart on the wiki), building a variety of software for different platforms – web, physical hardware, server side code, Hadoop, and mobile operating systems. They are broadly split in the following ways:
- Consumer Web Apps – desktop and mobile consumer websites, along with embedded native app websites
- Consumer iOS Apps – iOS apps for consumers
- Consumer Android Apps – Android apps for consumers
- Consumer Apps Test Automation – improving our test automation coverage across our consumer channels
- Business Apps – the internal apps and tools used to administer our business and provide great customer care
- Restaurant Apps – the devices and services used by our partner restaurants
- EPOS – the full-feature point of sale system we provide to restaurants
- Public APIs and web services – used by partners, internal clients and native apps
- Payments – payment authorisation, fraud checking, invoicing and financial reporting
- Order processing APIs – focusing on the APIs needed to place and fulfil orders
- Search APIs – building intelligent restaurant & menu search and associated APIs
- Platform Services – AWS automation, platform tools, infrastructure
Software is easy, talking is way harder. Like all organisations, problems can generally be avoided by just talking them through, and in an organisation with some teams, all working on different focuses, sometimes communicating can be a bit of a challenge. To try and help with this, we do a couple of things.
Firstly, teams tend to have their own little standup, or sit down meetings to kick off the day – these five minutes are vital for setting context and making sure that everyone knows what they’re meant to be doing. Don’t know? Just ask! There’s then a 5 minute meeting in the London office at around 10:30am each day, where each team sends a representative to try and make sure any cross-team dependencies are known, and get enough love. These meetings are super-low impact, and definitely should not be the only time you talk to your colleagues. Talk all the time. Ask for help. Pair. Anything that increases and encourages communication is a net win.
Obviously, you’re not always going to be in the same place, at the same time, so we use a couple of tools:
- HipChat – An IRC client on steroids. Each team has their own HipChat channel, so you’ll have to join the channels you’re interested in. On top of that, there are more general channels for “Monitoring and Alerting”, “API Consumers” and other special interest topics. Like lunch. Don’t forget lunch.
- Email – You should be issued with your Google apps credentials on your first day – we have an Engineering mailing list that you’ll be added to by default – but lets try not to use it too much.
- Calendars – Likewise, Google apps hosts our group calendars, including meeting room and projector bookings. Most of the meetings rooms don’t have equipment in them, so you’ll have to take your own device and book a projector by clicking “Rooms, etc.” in your meeting invite.
We also have breakout areas near the end of the office in London, with beanbags, standing desks and comfy chairs. Need a change of scene? Use them!
Knowing what to work on
Like all businesses, we have a set of strategic goals we aim for in each quarter – but only so many hands on keyboards, so we have to go through a prioritisation exercise to work out what we’re going to do. The Technical Lead of each team is the ultimate owner of work priority, and it’s their responsibility to work with product managers to organise and prioritise work around the goals of the company. That’s the long way of saying “if you’re not sure what to do, ask your Technical Lead, because a big part of their job is dealing with the complexity so you don’t have to”.
The stories we work on are captured in JIRA and available on your agile / greenhopper board. Broadly, the approach to work is Kanban / just-in-time, so try and respect that and only pull a single story at a time, focusing on throughput rather than concurrency.
Our general development work flow is:
- Select a task – from the top of the board
- Have a quick chat with your team about the task you’re pulling
- Have a quick chat with the product owner
- Write some tests
- Implement some code
- Make sure your code can be feature toggled off, if it’s a new user-visible feature
- Commit early and often
- Finish the task
- Ask a colleague to review your code
- Get your code deployed onto your team dev server and committed
- Deploy your code to the beta site feature toggled off
- Discuss production deployment with your team
Getting the code
We use GitHub Enterprise, a private install of GitHub hosted in our offices so you get all the good stuff associated with Git, along with the usability GitHub provides. When you start, go and sign up for an account and get your Technical Lead to add you to the GitHub organisation for your team.
Depending on your permissions, you’ll be able to either branch and merge in the team repository for projects you’re working on, or you’ll need to create a fork. You should keep your own forks of the code that you work on synchronised with upstream master, and use feature branches on your repository to make code changes.
Once you’re happy with your changes, submitting a pull request automagically invokes a build in TeamCity for your changes. TeamCity will add it’s own comments to your pull request, either flagging the pull request as “good to go” or “merge with caution”. Merge with caution means you broke the build, so try not to do that.
Keep your Git workflow simple, use branches to protect yourself from change, and commit early and often. Git is powerful, and fairly user-unfriendly, so if you’ve not used Git before, we recommend you at least skim through the Pro-Git book (digitally available for free online) to help you learn the ropes. TortoiseGit is also a decent, if slightly buggy Windows shell extension client, so if you’re not comfortable with bash command lines, use it to help. It echos out its command line invocations as it makes them, which is great for a git newbie.
We use a lot of different technology stacks and frameworks, but the things you’ll see the most of are:
- Ruby, Rake and Rake.Net (frequently for .NET builds and acceptance testing)
- ASP.NET WebForms and MVC
- OpenRasta – in “older” APIs
- PHP / MySQL for the EPOS system
- ServiceStack.Net – in “newer” APIs
- AWS features like EC2, SNS, Elastic MapReduce, Auto Scaling, DynamoDB and Route 53
- ORMs including FluentNHibernate, EntityFramework and Dapper
- Objective-C and Java in our mobile apps
Generally, you’ll need to know your C# and C# web frameworks, you’ll need to understand deployment within AWS, source control with Git and enough Ruby to write build and deployment scripts.
Teams have a lot of autonomy regarding internal implementation details, so if you want to use a specific technology, just discuss it with your team and decide between you if it’s a good fit.
Continuous integration is a vital part of good software development, and we use TeamCity for our CI. Working on an existing project is easy – each time your send a pull request, TeamCity will produce a build based on your branch. In order to ensure that your branch is integrated with the latest version of the code, make sure that you pull down the latest upstream code.
If you’re setting up a new project, we have some project templates available in TeamCity, make sure you use the VCS root General git parameterised shared-all VCS root which will force you to provide a few build parameters (branch, name, repo_owner) but do all the heavy lifting for you. At this point, just configure your project how you see fit.
We have an internal NuGet server available for you to publish NuGet packages to, so make use of it as you see fit.
- JustEat.Testing – BDD wrapper for nunit/xunit with low ceremony pit-of-success encouragement
- JustEat.StatsD – formatter and publisher for statsd/graphite metrics…
- … we use statsd and graphite for real-time monitoring. You should too, it’s really easy. Forget everything you knew about performance counters, you don’t need it here.
External libraries we tend to use by consensus
These aren’t hard and fast constraints, just things that people tend to use by default:
- Logging – nlog
- Web framework – APIs
- OpenRasta – but it’s not actively developed anymore
- ServiceStack – we use 3.9.x
- IoC – each team tends to pick the one they know most
- Testing – mostly nunit. Some xunit. See JustEat.Testing above.
- Windows services – TopShelf
- Build automation & dependencies – rake
- Functional testing – cucumber
Deployment typically happens as part of our AWS Auto Scaling. We use TeamCity to generate deployment packages, push them to S3, and then for our QA environments, terminate our test instances. At this point Amazon CFInit will replace the server and the latest package will be pulled from S3 and installed – the process takes around 15-20 minutes.
The process for production is similar, except rather than terminating instances, we scale up, then scale down, terminating the old instances once the new ones have all initialised.
There is on-going work to further automate this process.
How do I know my code is good to go?
Knowing when your code is good enough to go is a continual conversation between you and your team – but there are obviously a couple of things to make sure of:
- Your code has no ReSharper corrections – a first line of defence, make sure your code is clean as per the ReSharper style file associated with your project. Avoid comment based exclusions to just “make it pass”, instead prefer to update the conventions file for your project so everyone gets the benefit.
- You have a high percentage of test coverage – A lot of our builds will fail for cleanliness reasons if your code coverage is too low. You did TDD that code didn’t you?
- You’ve got functional test coverage – Our DVTs let us know when things work, they’re important, make sure they exist for your new features
- You’ve done a refactor pass – Remember you probably won’t be the next person to look at the code you’ve just written – make that person happy to see it.
Code reviews can take two obvious forms – if you’ve paired for the duration of building the code, it’s redundant – you’ve just done a continual code review! If you haven’t paired, you’re going to need to get a second set of eyes on your changes, for sanity. The process for this varies from team to team, but in teams that use pull requests as a marker for “done”, the person who deals with your pull request into the main repository will review your code, leaving comments, and suggesting changes. If you’re doing a review, do the same!
When you’re reviewing code, make sure you check for the key characteristics of good code, is it idiomatic,clean, readable, tested and working. Make sure the code sticks to the internal standards of the project, make sure the code adheres to solid principles and passes a sanity check for the principle of least surprise.
Unit testing and testing standards
Most teams follow a BDD approach to testing code, using our internally curated BehaviourTest library. It’s based on NUnit and uses AutoFixture to mock out your dependencies, so don’t worry, it’s not scary. Follow the standards and examples in the existing code for guidance – but keep in mind you should be testing “contexts and behaviours” rather than just methods. Test first is heavily encouraged, but again, project conventions may vary.
p>Our EC2 instances have a log shipper installed, which copies logs to S3. It automatically scans your deployment directory and any subdirectories for a any directories named logs – and ships the logs every 10 minutes – so make sure your NLog/log4xxx code targets a named directory.